use std::{collections::BTreeMap, sync::Arc};
use jsonrpsee::RpcModule;
use sc_client_api::{
backend::{Backend, StorageProvider},
client::BlockchainEvents,
AuxStore, UsageProvider,
};
use sc_network::NetworkService;
use sc_network_sync::SyncingService;
use sc_rpc::SubscriptionTaskExecutor;
use sc_transaction_pool::{ChainApi, Pool};
use sc_transaction_pool_api::TransactionPool;
use sp_api::{CallApiAt, ProvideRuntimeApi};
use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi};
use sp_core::H256;
use sp_inherents::CreateInherentDataProviders;
use sp_runtime::traits::Block as BlockT;
pub use fc_rpc::{EthBlockDataCacheTask, EthConfig, OverrideHandle};
pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool};
pub use fc_storage::overrides_handle;
use fp_rpc::{ConvertTransaction, ConvertTransactionRuntimeApi, EthereumRuntimeRPCApi};
pub struct EthDeps<B: BlockT, C, P, A: ChainApi, CT, CIDP> {
pub client: Arc<C>,
pub pool: Arc<P>,
pub graph: Arc<Pool<A>>,
pub converter: Option<CT>,
pub is_authority: bool,
pub enable_dev_signer: bool,
pub network: Arc<NetworkService<B, B::Hash>>,
pub sync: Arc<SyncingService<B>>,
pub frontier_backend: Arc<dyn fc_api::Backend<B>>,
pub overrides: Arc<OverrideHandle<B>>,
pub block_data_cache: Arc<EthBlockDataCacheTask<B>>,
pub filter_pool: Option<FilterPool>,
pub max_past_logs: u32,
pub fee_history_cache: FeeHistoryCache,
pub fee_history_cache_limit: FeeHistoryCacheLimit,
pub execute_gas_limit_multiplier: u64,
pub forced_parent_hashes: Option<BTreeMap<H256, H256>>,
pub pending_create_inherent_data_providers: CIDP,
}
pub fn create_eth<B, C, BE, P, A, CT, CIDP, EC>(
mut io: RpcModule<()>,
deps: EthDeps<B, C, P, A, CT, CIDP>,
subscription_task_executor: SubscriptionTaskExecutor,
pubsub_notification_sinks: Arc<
fc_mapping_sync::EthereumBlockNotificationSinks<
fc_mapping_sync::EthereumBlockNotification<B>,
>,
>,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
B: BlockT<Hash = H256>,
C: CallApiAt<B> + ProvideRuntimeApi<B>,
C::Api: AuraApi<B, AuraId>
+ BlockBuilderApi<B>
+ ConvertTransactionRuntimeApi<B>
+ EthereumRuntimeRPCApi<B>,
C: HeaderBackend<B> + HeaderMetadata<B, Error = BlockChainError>,
C: BlockchainEvents<B> + AuxStore + UsageProvider<B> + StorageProvider<B, BE> + 'static,
BE: Backend<B> + 'static,
P: TransactionPool<Block = B> + 'static,
A: ChainApi<Block = B> + 'static,
CT: ConvertTransaction<<B as BlockT>::Extrinsic> + Send + Sync + 'static,
CIDP: CreateInherentDataProviders<B, ()> + Send + 'static,
EC: EthConfig<B, C>,
{
use fc_rpc::{
pending::AuraConsensusDataProvider, Debug, DebugApiServer, Eth, EthApiServer, EthDevSigner,
EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, NetApiServer,
Web3, Web3ApiServer,
};
#[cfg(feature = "txpool")]
use fc_rpc::{TxPool, TxPoolApiServer};
let EthDeps {
client,
pool,
graph,
converter,
is_authority,
enable_dev_signer,
network,
sync,
frontier_backend,
overrides,
block_data_cache,
filter_pool,
max_past_logs,
fee_history_cache,
fee_history_cache_limit,
execute_gas_limit_multiplier,
forced_parent_hashes,
pending_create_inherent_data_providers,
} = deps;
let mut signers = Vec::new();
if enable_dev_signer {
signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
}
io.merge(
Eth::<B, C, P, CT, BE, A, CIDP, EC>::new(
client.clone(),
pool.clone(),
graph.clone(),
converter,
sync.clone(),
signers,
overrides.clone(),
frontier_backend.clone(),
is_authority,
block_data_cache.clone(),
fee_history_cache,
fee_history_cache_limit,
execute_gas_limit_multiplier,
forced_parent_hashes,
pending_create_inherent_data_providers,
Some(Box::new(AuraConsensusDataProvider::new(client.clone()))),
)
.replace_config::<EC>()
.into_rpc(),
)?;
if let Some(filter_pool) = filter_pool {
io.merge(
EthFilter::new(
client.clone(),
frontier_backend.clone(),
graph.clone(),
filter_pool,
500_usize, max_past_logs,
block_data_cache.clone(),
)
.into_rpc(),
)?;
}
io.merge(
EthPubSub::new(
pool,
client.clone(),
sync,
subscription_task_executor,
overrides.clone(),
pubsub_notification_sinks,
)
.into_rpc(),
)?;
io.merge(
Net::new(
client.clone(),
network,
true,
)
.into_rpc(),
)?;
io.merge(Web3::new(client.clone()).into_rpc())?;
io.merge(
Debug::new(
client.clone(),
frontier_backend,
overrides,
block_data_cache,
)
.into_rpc(),
)?;
#[cfg(feature = "txpool")]
io.merge(TxPool::new(client, graph).into_rpc())?;
Ok(io)
}