1use sp_runtime::traits::BlakeTwo256;2use unique_runtime::{Hash, AccountId, CrossAccountId, Index, opaque::Block, BlockNumber, Balance};3use fc_rpc::{4 EthBlockDataCache, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,5 StorageOverride, SchemaV2Override, SchemaV3Override,6};7use fc_rpc_core::types::{FilterPool, FeeHistoryCache};8use jsonrpc_pubsub::manager::SubscriptionManager;9use pallet_ethereum::EthereumStorageSchema;10use sc_client_api::{11 backend::{AuxStore, StorageProvider},12 client::BlockchainEvents,13 StateBackend, Backend,14};15use sc_finality_grandpa::{16 FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,17};18use sc_network::NetworkService;19use sc_rpc::SubscriptionTaskExecutor;20pub use sc_rpc_api::DenyUnsafe;21use sc_transaction_pool::{ChainApi, Pool};22use sp_api::ProvideRuntimeApi;23use sp_block_builder::BlockBuilder;24use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};25use sc_service::TransactionPool;26use std::{collections::BTreeMap, marker::PhantomData, sync::Arc};272829pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;303132pub struct GrandpaDeps<B> {33 34 pub shared_voter_state: SharedVoterState,35 36 pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,37 38 pub justification_stream: GrandpaJustificationStream<Block>,39 40 pub subscription_executor: SubscriptionTaskExecutor,41 42 pub finality_provider: Arc<FinalityProofProvider<B, Block>>,43}444546pub struct FullDeps<C, P, SC, CA: ChainApi> {47 48 pub client: Arc<C>,49 50 pub pool: Arc<P>,51 52 pub graph: Arc<Pool<CA>>,53 54 pub select_chain: SC,55 56 pub is_authority: bool,57 58 pub enable_dev_signer: bool,59 60 pub network: Arc<NetworkService<Block, Hash>>,61 62 pub deny_unsafe: DenyUnsafe,63 64 pub filter_pool: Option<FilterPool>,65 66 pub backend: Arc<fc_db::Backend<Block>>,67 68 pub max_past_logs: u32,69 70 pub fee_history_limit: u64,71 72 pub fee_history_cache: FeeHistoryCache,73 74 pub block_data_cache: Arc<EthBlockDataCache<Block>>,75}7677struct AccountCodes<C, B> {78 client: Arc<C>,79 _marker: PhantomData<B>,80}8182impl<C, Block> AccountCodes<C, Block>83where84 Block: sp_api::BlockT,85 C: ProvideRuntimeApi<Block>,86{87 fn new(client: Arc<C>) -> Self {88 Self {89 client,90 _marker: PhantomData,91 }92 }93}9495impl<C, Block> fc_rpc::AccountCodeProvider<Block> for AccountCodes<C, Block>96where97 Block: sp_api::BlockT,98 C: ProvideRuntimeApi<Block>,99 C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,100{101 fn code(&self, block: &sp_api::BlockId<Block>, account: sp_core::H160) -> Option<Vec<u8>> {102 use up_rpc::UniqueApi;103 self.client104 .runtime_api()105 .eth_contract_code(block, account)106 .ok()107 .flatten()108 }109}110111pub fn overrides_handle<C, BE>(client: Arc<C>) -> Arc<OverrideHandle<Block>>112where113 C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,114 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,115 C: Send + Sync + 'static,116 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,117 C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,118 BE: Backend<Block> + 'static,119 BE::State: StateBackend<BlakeTwo256>,120{121 let mut overrides_map = BTreeMap::new();122 overrides_map.insert(123 EthereumStorageSchema::V1,124 Box::new(SchemaV1Override::new_with_code_provider(125 client.clone(),126 Arc::new(AccountCodes::<C, Block>::new(client.clone())),127 )) as Box<dyn StorageOverride<_> + Send + Sync>,128 );129 overrides_map.insert(130 EthereumStorageSchema::V2,131 Box::new(SchemaV2Override::new(client.clone()))132 as Box<dyn StorageOverride<_> + Send + Sync>,133 );134 overrides_map.insert(135 EthereumStorageSchema::V3,136 Box::new(SchemaV3Override::new(client.clone()))137 as Box<dyn StorageOverride<_> + Send + Sync>,138 );139140 Arc::new(OverrideHandle {141 schemas: overrides_map,142 fallback: Box::new(RuntimeApiStorageOverride::new(client)),143 })144}145146147pub fn create_full<C, P, SC, CA, A, B>(148 deps: FullDeps<C, P, SC, CA>,149 subscription_task_executor: SubscriptionTaskExecutor,150) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata>151where152 C: ProvideRuntimeApi<Block> + StorageProvider<Block, B> + AuxStore,153 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,154 C: Send + Sync + 'static,155 C: BlockchainEvents<Block>,156 C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,157 C::Api: BlockBuilder<Block>,158 159 C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,160 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,161 C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,162 B: sc_client_api::Backend<Block> + Send + Sync + 'static,163 B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,164 P: TransactionPool<Block = Block> + 'static,165 CA: ChainApi<Block = Block> + 'static,166{167 use fc_rpc::{168 EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi,169 EthPubSubApiServer, EthSigner, HexEncodedIdProvider, NetApi, NetApiServer, Web3Api,170 Web3ApiServer,171 };172 use uc_rpc::{UniqueApi, Unique};173 174 use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};175 use substrate_frame_rpc_system::{FullSystem, SystemApi};176177 let mut io = jsonrpc_core::IoHandler::default();178 let FullDeps {179 client,180 pool,181 graph,182 select_chain: _,183 fee_history_limit,184 fee_history_cache,185 block_data_cache,186 enable_dev_signer,187 is_authority,188 network,189 deny_unsafe,190 filter_pool,191 backend,192 max_past_logs,193 } = deps;194195 io.extend_with(SystemApi::to_delegate(FullSystem::new(196 client.clone(),197 pool.clone(),198 deny_unsafe,199 )));200201 io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(202 client.clone(),203 )));204205 206207 let mut signers = Vec::new();208 if enable_dev_signer {209 signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);210 }211212 let overrides = overrides_handle(client.clone());213214 io.extend_with(EthApiServer::to_delegate(EthApi::new(215 client.clone(),216 pool.clone(),217 graph,218 unique_runtime::TransactionConverter,219 network.clone(),220 signers,221 overrides.clone(),222 backend.clone(),223 is_authority,224 max_past_logs,225 block_data_cache.clone(),226 fee_history_limit,227 fee_history_cache,228 )));229 io.extend_with(UniqueApi::to_delegate(Unique::new(client.clone())));230231 if let Some(filter_pool) = filter_pool {232 io.extend_with(EthFilterApiServer::to_delegate(EthFilterApi::new(233 client.clone(),234 backend,235 filter_pool,236 500_usize, 237 max_past_logs,238 block_data_cache,239 )));240 }241242 io.extend_with(NetApiServer::to_delegate(NetApi::new(243 client.clone(),244 network.clone(),245 246 true,247 )));248249 io.extend_with(Web3ApiServer::to_delegate(Web3Api::new(client.clone())));250251 io.extend_with(EthPubSubApiServer::to_delegate(EthPubSubApi::new(252 pool,253 client,254 network,255 SubscriptionManager::<HexEncodedIdProvider>::with_id_provider(256 HexEncodedIdProvider::default(),257 Arc::new(subscription_task_executor),258 ),259 overrides,260 )));261262 io263}