git.delta.rocks / unique-network / refs/commits / ec57cb9db90d

difftreelog

refactor ethereum RPC/tasks initialization

Yaroslav Bolyukin2023-06-16parent: #f28d992.patch.diff
in: master

7 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6507,11 +6507,13 @@
  "frame-benchmarking",
  "frame-support",
  "frame-system",
+ "hex-literal",
  "parity-scale-codec",
  "scale-info",
  "smallvec",
  "sp-arithmetic",
  "sp-core",
+ "sp-io",
  "sp-std",
  "xcm",
 ]
@@ -13841,9 +13843,11 @@
  "fc-rpc",
  "fc-rpc-core",
  "fp-rpc",
+ "fp-storage",
  "frame-benchmarking",
  "frame-benchmarking-cli",
  "futures",
+ "jsonrpsee",
  "log",
  "opal-runtime",
  "pallet-transaction-payment-rpc-runtime-api",
@@ -13861,6 +13865,7 @@
  "sc-executor",
  "sc-network",
  "sc-network-sync",
+ "sc-rpc",
  "sc-service",
  "sc-sysinfo",
  "sc-telemetry",
@@ -13906,9 +13911,9 @@
  "fp-rpc",
  "fp-storage",
  "jsonrpsee",
+ "pallet-ethereum",
  "pallet-transaction-payment-rpc",
  "sc-client-api",
- "sc-consensus-grandpa",
  "sc-network",
  "sc-network-sync",
  "sc-rpc",
modifiedCargo.tomldiffbeforeafterboth
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -125,7 +125,6 @@
 sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
 sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
 sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
-sc-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
 sc-consensus-manual-seal = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
 sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
 sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
modifiednode/cli/Cargo.tomldiffbeforeafterboth
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -21,7 +21,7 @@
 
 [dependencies]
 clap = "4.1"
-futures = '0.3.17'
+futures = '0.3.28'
 tokio = { version = "1.24", features = ["time"] }
 serde_json = "1.0"
 
@@ -94,6 +94,9 @@
 unique-rpc = { workspace = true }
 up-pov-estimate-rpc = { workspace = true }
 up-rpc = { workspace = true }
+jsonrpsee.workspace = true
+fp-storage.workspace = true
+sc-rpc.workspace = true
 
 [build-dependencies]
 substrate-build-script-utils = { workspace = true }
modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -168,6 +168,7 @@
 					.collect(),
 			},
 			common: Default::default(),
+			configuration: Default::default(),
 			nonfungible: Default::default(),
 			treasury: Default::default(),
 			tokens: TokensConfig { balances: vec![] },
@@ -228,6 +229,7 @@
 					.to_vec(),
 			},
 			common: Default::default(),
+			configuration: Default::default(),
 			nonfungible: Default::default(),
 			balances: BalancesConfig {
 				balances: $endowed_accounts
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -20,16 +20,19 @@
 use std::collections::BTreeMap;
 use std::time::Duration;
 use std::pin::Pin;
+use fc_mapping_sync::EthereumBlockNotificationSinks;
+use fc_rpc::EthBlockDataCacheTask;
+use fc_rpc::EthTask;
 use fc_rpc_core::types::FeeHistoryCache;
 use futures::{
 	Stream, StreamExt,
 	stream::select,
 	task::{Context, Poll},
 };
+use sc_rpc::SubscriptionTaskExecutor;
 use sp_keystore::KeystorePtr;
 use tokio::time::Interval;
-
-use unique_rpc::overrides_handle;
+use jsonrpsee::RpcModule;
 
 use serde::{Serialize, Deserialize};
 
@@ -49,7 +52,7 @@
 use cumulus_relay_chain_minimal_node::build_minimal_relay_chain_node;
 
 // Substrate Imports
-use sp_api::BlockT;
+use sp_api::{BlockT, HeaderT, ProvideRuntimeApi, StateBackend};
 use sc_executor::NativeElseWasmExecutor;
 use sc_executor::NativeExecutionDispatch;
 use sc_network::NetworkBlock;
@@ -58,14 +61,23 @@
 use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};
 use sp_runtime::traits::BlakeTwo256;
 use substrate_prometheus_endpoint::Registry;
-use sc_client_api::BlockchainEvents;
+use sc_client_api::{BlockchainEvents, BlockOf, Backend, AuxStore, StorageProvider};
+use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError};
 use sc_consensus::ImportQueue;
+use sp_core::H256;
+use sp_block_builder::BlockBuilder;
 
 use polkadot_service::CollatorPair;
 
 // Frontier Imports
 use fc_rpc_core::types::FilterPool;
 use fc_mapping_sync::{kv::MappingSyncWorker, SyncStrategy};
+use fc_rpc::{
+	StorageOverride, OverrideHandle, SchemaV1Override, SchemaV2Override, SchemaV3Override,
+	RuntimeApiStorageOverride,
+};
+use fp_rpc::EthereumRuntimeRPCApi;
+use fp_storage::EthereumStorageSchema;
 
 use up_common::types::opaque::*;
 
@@ -173,7 +185,7 @@
 	}
 }
 
-pub fn open_frontier_backend<Block: BlockT, C: sp_blockchain::HeaderBackend<Block>>(
+pub fn open_frontier_backend<Block: BlockT, C: HeaderBackend<Block>>(
 	client: Arc<C>,
 	config: &Configuration,
 ) -> Result<Arc<fc_db::kv::Backend<Block>>, String> {
@@ -213,13 +225,7 @@
 		FullSelectChain,
 		sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
 		sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
-		(
-			Option<Telemetry>,
-			Option<FilterPool>,
-			Arc<fc_db::kv::Backend<Block>>,
-			Option<TelemetryWorkerHandle>,
-			FeeHistoryCache,
-		),
+		OtherPartial,
 	>,
 	sc_service::Error,
 >
@@ -242,17 +248,6 @@
 		sc_service::Error,
 	>,
 {
-	let _telemetry = config
-		.telemetry_endpoints
-		.clone()
-		.filter(|x| !x.is_empty())
-		.map(|endpoints| -> Result<_, sc_telemetry::Error> {
-			let worker = TelemetryWorker::new(16)?;
-			let telemetry = worker.handle().new_telemetry(endpoints);
-			Ok((worker, telemetry))
-		})
-		.transpose()?;
-
 	let telemetry = config
 		.telemetry_endpoints
 		.clone()
@@ -293,9 +288,9 @@
 		client.clone(),
 	);
 
-	let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));
+	let eth_filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));
 
-	let frontier_backend = open_frontier_backend(client.clone(), config)?;
+	let eth_backend = open_frontier_backend(client.clone(), config)?;
 
 	let import_queue = build_import_queue(
 		client.clone(),
@@ -304,7 +299,6 @@
 		telemetry.as_ref().map(|telemetry| telemetry.handle()),
 		&task_manager,
 	)?;
-	let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));
 
 	let params = PartialComponents {
 		backend,
@@ -314,13 +308,12 @@
 		task_manager,
 		transaction_pool,
 		select_chain,
-		other: (
+		other: OtherPartial {
 			telemetry,
-			filter_pool,
-			frontier_backend,
+			eth_filter_pool,
+			eth_backend,
 			telemetry_worker_handle,
-			fee_history_cache,
-		),
+		},
 	};
 
 	Ok(params)
@@ -427,8 +420,12 @@
 
 	let params =
 		new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(&parachain_config, build_import_queue)?;
-	let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =
-		params.other;
+	let OtherPartial {
+		mut telemetry,
+		telemetry_worker_handle,
+		eth_filter_pool,
+		eth_backend,
+	} = params.other;
 	let net_config = sc_network::config::FullNetworkConfiguration::new(&parachain_config.network);
 
 	let client = params.client.clone();
@@ -470,69 +467,72 @@
 
 	let select_chain = params.select_chain.clone();
 
-	let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(
-		task_manager.spawn_handle(),
-		overrides_handle::<_, _, Runtime>(client.clone()),
-		50,
-		50,
-		prometheus_registry.clone(),
-	));
+	let runtime_id = parachain_config.chain_spec.runtime_id();
 
-	let pubsub_notification_sinks: fc_mapping_sync::EthereumBlockNotificationSinks<
-		fc_mapping_sync::EthereumBlockNotification<Block>,
+	// Frontier
+	let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));
+	let fee_history_limit = 2048;
+
+	let eth_pubsub_notification_sinks: Arc<
+		EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,
 	> = Default::default();
-	let pubsub_notification_sinks = Arc::new(pubsub_notification_sinks);
 
-	task_manager.spawn_essential_handle().spawn(
-		"frontier-mapping-sync-worker",
-		Some("frontier"),
-		MappingSyncWorker::new(
-			client.import_notification_stream(),
-			Duration::new(6, 0),
-			client.clone(),
-			backend.clone(),
-			overrides_handle::<_, _, Runtime>(client.clone()),
-			frontier_backend.clone(),
-			3,
-			0,
-			SyncStrategy::Parachain,
-			sync_service.clone(),
-			pubsub_notification_sinks.clone(),
-		)
-		.for_each(|()| futures::future::ready(())),
+	let overrides = overrides_handle(client.clone());
+	let eth_block_data_cache = spawn_frontier_tasks(
+		FrontierTaskParams {
+			client: client.clone(),
+			substrate_backend: backend.clone(),
+			eth_filter_pool: eth_filter_pool.clone(),
+			eth_backend: eth_backend.clone(),
+			fee_history_limit,
+			fee_history_cache: fee_history_cache.clone(),
+			task_manager: &task_manager,
+			prometheus_registry: prometheus_registry.clone(),
+			overrides: overrides.clone(),
+			sync_strategy: SyncStrategy::Parachain,
+		},
+		sync_service.clone(),
+		eth_pubsub_notification_sinks.clone(),
 	);
 
-	let runtime_id = parachain_config.chain_spec.runtime_id();
-
+	// Rpc
 	let rpc_builder = Box::new({
 		clone!(
 			client,
 			backend,
-			pubsub_notification_sinks,
+			eth_backend,
+			eth_pubsub_notification_sinks,
+			fee_history_cache,
+			eth_block_data_cache,
+			overrides,
 			transaction_pool,
 			network,
 			sync_service,
-			frontier_backend,
 		);
-		move |deny_unsafe, subscription_task_executor| {
+		move |deny_unsafe, subscription_task_executor: SubscriptionTaskExecutor| {
 			clone!(
 				backend,
-				runtime_id,
+				eth_block_data_cache,
 				client,
-				transaction_pool,
-				filter_pool,
+				eth_backend,
+				eth_filter_pool,
+				eth_pubsub_notification_sinks,
+				fee_history_cache,
+				eth_block_data_cache,
 				network,
+				runtime_id,
+				transaction_pool,
 				select_chain,
-				block_data_cache,
-				fee_history_cache,
-				pubsub_notification_sinks,
-				frontier_backend,
+				overrides,
 			);
 
 			#[cfg(not(feature = "pov-estimate"))]
 			let _ = backend;
 
+			let mut rpc_handle = RpcModule::new(());
+
 			let full_deps = unique_rpc::FullDeps {
+				client: client.clone(),
 				runtime_id,
 
 				#[cfg(feature = "pov-estimate")]
@@ -546,32 +546,40 @@
 				#[cfg(feature = "pov-estimate")]
 				backend,
 
-				eth_backend: frontier_backend,
 				deny_unsafe,
+				pool: transaction_pool.clone(),
+				select_chain,
+			};
+
+			unique_rpc::create_full::<_, _, _, Runtime, RuntimeApi, _>(&mut rpc_handle, full_deps)?;
+
+			let eth_deps = unique_rpc::EthDeps {
 				client,
 				graph: transaction_pool.pool().clone(),
 				pool: transaction_pool,
-				// TODO: Unhardcode
-				enable_dev_signer: false,
-				filter_pool,
+				is_authority: validator,
 				network,
-				sync: sync_service.clone(),
-				select_chain,
-				is_authority: validator,
+				eth_backend,
 				// TODO: Unhardcode
 				max_past_logs: 10000,
-				block_data_cache,
+				fee_history_limit,
 				fee_history_cache,
+				eth_block_data_cache,
 				// TODO: Unhardcode
-				fee_history_limit: 2048,
-				pubsub_notification_sinks,
+				enable_dev_signer: false,
+				eth_filter_pool,
+				eth_pubsub_notification_sinks,
+				overrides,
+				sync: sync_service.clone(),
 			};
 
-			unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(
-				full_deps,
-				subscription_task_executor,
-			)
-			.map_err(Into::into)
+			unique_rpc::create_eth(
+				&mut rpc_handle,
+				eth_deps,
+				subscription_task_executor.clone(),
+			)?;
+
+			Ok(rpc_handle)
 		}
 	});
 
@@ -866,6 +874,13 @@
 	))
 }
 
+pub struct OtherPartial {
+	pub telemetry: Option<Telemetry>,
+	pub telemetry_worker_handle: Option<TelemetryWorkerHandle>,
+	pub eth_filter_pool: Option<FilterPool>,
+	pub eth_backend: Arc<fc_db::kv::Backend<Block>>,
+}
+
 /// Builds a new development service. This service uses instant seal, and mocks
 /// the parachain inherent
 pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(
@@ -899,7 +914,6 @@
 {
 	use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams};
 	use fc_consensus::FrontierBlockImport;
-	use sc_client_api::HeaderBackend;
 
 	let sc_service::PartialComponents {
 		client,
@@ -910,7 +924,12 @@
 		select_chain: maybe_select_chain,
 		transaction_pool,
 		other:
-			(telemetry, filter_pool, frontier_backend, _telemetry_worker_handle, fee_history_cache),
+			OtherPartial {
+				telemetry,
+				eth_filter_pool,
+				eth_backend,
+				telemetry_worker_handle: _,
+			},
 	} = new_partial::<RuntimeApi, ExecutorDispatch, _>(
 		&config,
 		dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,
@@ -918,19 +937,6 @@
 	let net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);
 	let prometheus_registry = config.prometheus_registry().cloned();
 
-	let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(
-		task_manager.spawn_handle(),
-		overrides_handle::<_, _, Runtime>(client.clone()),
-		50,
-		50,
-		prometheus_registry.clone(),
-	));
-
-	let pubsub_notification_sinks: fc_mapping_sync::EthereumBlockNotificationSinks<
-		fc_mapping_sync::EthereumBlockNotification<Block>,
-	> = Default::default();
-	let pubsub_notification_sinks = Arc::new(pubsub_notification_sinks);
-
 	let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
 		sc_service::build_network(sc_service::BuildNetworkParams {
 			config: &config,
@@ -1046,57 +1052,76 @@
 			}),
 		);
 	}
-
-	task_manager.spawn_essential_handle().spawn(
-		"frontier-mapping-sync-worker",
-		Some("block-authoring"),
-		MappingSyncWorker::new(
-			client.import_notification_stream(),
-			Duration::new(6, 0),
-			client.clone(),
-			backend.clone(),
-			overrides_handle::<_, _, Runtime>(client.clone()),
-			frontier_backend.clone(),
-			3,
-			0,
-			SyncStrategy::Normal,
-			sync_service.clone(),
-			pubsub_notification_sinks.clone(),
-		)
-		.for_each(|()| futures::future::ready(())),
-	);
 
 	#[cfg(feature = "pov-estimate")]
 	let rpc_backend = backend.clone();
 
 	let runtime_id = config.chain_spec.runtime_id();
 
+	// Frontier
+	let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));
+	let fee_history_limit = 2048;
+
+	let eth_pubsub_notification_sinks: Arc<
+		EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,
+	> = Default::default();
+
+	let overrides = overrides_handle(client.clone());
+	let eth_block_data_cache = spawn_frontier_tasks(
+		FrontierTaskParams {
+			client: client.clone(),
+			substrate_backend: backend.clone(),
+			eth_filter_pool: eth_filter_pool.clone(),
+			eth_backend: eth_backend.clone(),
+			fee_history_limit,
+			fee_history_cache: fee_history_cache.clone(),
+			task_manager: &task_manager,
+			prometheus_registry,
+			overrides: overrides.clone(),
+			sync_strategy: SyncStrategy::Normal,
+		},
+		sync_service.clone(),
+		eth_pubsub_notification_sinks.clone(),
+	);
+
+	// Rpc
 	let rpc_builder = Box::new({
 		clone!(
-			backend,
 			client,
-			sync_service,
-			frontier_backend,
+			backend,
+			eth_backend,
+			eth_pubsub_notification_sinks,
+			fee_history_cache,
+			eth_block_data_cache,
+			overrides,
+			transaction_pool,
 			network,
-			transaction_pool,
-			pubsub_notification_sinks
+			sync_service,
 		);
-		move |deny_unsafe, subscription_executor| {
+		move |deny_unsafe, subscription_task_executor: SubscriptionTaskExecutor| {
 			clone!(
 				backend,
-				block_data_cache,
+				eth_block_data_cache,
 				client,
+				eth_backend,
+				eth_filter_pool,
+				eth_pubsub_notification_sinks,
 				fee_history_cache,
-				filter_pool,
+				eth_block_data_cache,
 				network,
-				pubsub_notification_sinks,
+				runtime_id,
+				transaction_pool,
+				select_chain,
+				overrides,
 			);
 
 			#[cfg(not(feature = "pov-estimate"))]
 			let _ = backend;
 
+			let mut rpc_module = RpcModule::new(());
+
 			let full_deps = unique_rpc::FullDeps {
-				runtime_id: runtime_id.clone(),
+				runtime_id,
 
 				#[cfg(feature = "pov-estimate")]
 				exec_params: uc_rpc::pov_estimate::ExecutorParams {
@@ -1108,32 +1133,42 @@
 
 				#[cfg(feature = "pov-estimate")]
 				backend,
-				eth_backend: frontier_backend.clone(),
+				// eth_backend,
 				deny_unsafe,
-				client,
+				client: client.clone(),
 				pool: transaction_pool.clone(),
+				select_chain,
+			};
+
+			unique_rpc::create_full::<_, _, _, Runtime, RuntimeApi, _>(&mut rpc_module, full_deps)?;
+
+			let eth_deps = unique_rpc::EthDeps {
+				client,
 				graph: transaction_pool.pool().clone(),
-				// TODO: Unhardcode
-				enable_dev_signer: false,
-				filter_pool,
+				pool: transaction_pool,
+				is_authority: true,
 				network,
-				sync: sync_service.clone(),
-				select_chain: select_chain.clone(),
-				is_authority: collator,
+				eth_backend,
 				// TODO: Unhardcode
 				max_past_logs: 10000,
-				block_data_cache,
+				fee_history_limit,
 				fee_history_cache,
+				eth_block_data_cache,
 				// TODO: Unhardcode
-				fee_history_limit: 2048,
-				pubsub_notification_sinks,
+				enable_dev_signer: false,
+				eth_filter_pool,
+				eth_pubsub_notification_sinks,
+				overrides,
+				sync: sync_service.clone(),
 			};
 
-			unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(
-				full_deps,
-				subscription_executor,
-			)
-			.map_err(Into::into)
+			unique_rpc::create_eth(
+				&mut rpc_module,
+				eth_deps,
+				subscription_task_executor.clone(),
+			)?;
+
+			Ok(rpc_module)
 		}
 	});
 
@@ -1155,3 +1190,130 @@
 	network_starter.start_network();
 	Ok(task_manager)
 }
+
+fn overrides_handle<C, BE>(client: Arc<C>) -> Arc<OverrideHandle<Block>>
+where
+	C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,
+	C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,
+	C: Send + Sync + 'static,
+	C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
+	BE: Backend<Block> + 'static,
+	BE::State: StateBackend<BlakeTwo256>,
+{
+	let mut overrides_map = BTreeMap::new();
+	overrides_map.insert(
+		EthereumStorageSchema::V1,
+		Box::new(SchemaV1Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,
+	);
+	overrides_map.insert(
+		EthereumStorageSchema::V2,
+		Box::new(SchemaV2Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,
+	);
+	overrides_map.insert(
+		EthereumStorageSchema::V3,
+		Box::new(SchemaV3Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,
+	);
+
+	Arc::new(OverrideHandle {
+		schemas: overrides_map,
+		fallback: Box::new(RuntimeApiStorageOverride::new(client)),
+	})
+}
+
+pub struct FrontierTaskParams<'a, B: BlockT, C, BE> {
+	pub task_manager: &'a TaskManager,
+	pub client: Arc<C>,
+	pub substrate_backend: Arc<BE>,
+	pub eth_backend: Arc<fc_db::kv::Backend<B>>,
+	pub eth_filter_pool: Option<FilterPool>,
+	pub overrides: Arc<OverrideHandle<B>>,
+	pub fee_history_limit: u64,
+	pub fee_history_cache: FeeHistoryCache,
+	pub sync_strategy: SyncStrategy,
+	pub prometheus_registry: Option<Registry>,
+}
+
+pub fn spawn_frontier_tasks<B, C, BE>(
+	params: FrontierTaskParams<B, C, BE>,
+	sync: Arc<SyncingService<B>>,
+	pubsub_notification_sinks: Arc<
+		EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<B>>,
+	>,
+) -> Arc<EthBlockDataCacheTask<B>>
+where
+	C: ProvideRuntimeApi<B> + BlockOf,
+	C: HeaderBackend<B> + HeaderMetadata<B, Error = BlockChainError> + 'static,
+	C: BlockchainEvents<B> + StorageProvider<B, BE>,
+	C: Send + Sync + 'static,
+	C::Api: EthereumRuntimeRPCApi<B>,
+	C::Api: BlockBuilder<B>,
+	B: BlockT<Hash = H256> + Send + Sync + 'static,
+	B::Header: HeaderT<Number = u32>,
+	BE: Backend<B> + 'static,
+	BE::State: StateBackend<BlakeTwo256>,
+{
+	let FrontierTaskParams {
+		task_manager,
+		client,
+		substrate_backend,
+		eth_backend,
+		eth_filter_pool,
+		overrides,
+		fee_history_limit,
+		fee_history_cache,
+		sync_strategy,
+		prometheus_registry,
+	} = params;
+	// Frontier offchain DB task. Essential.
+	// Maps emulated ethereum data to substrate native data.
+	params.task_manager.spawn_essential_handle().spawn(
+		"frontier-mapping-sync-worker",
+		Some("frontier"),
+		MappingSyncWorker::new(
+			client.import_notification_stream(),
+			Duration::new(6, 0),
+			client.clone(),
+			substrate_backend,
+			overrides.clone(),
+			eth_backend,
+			3,
+			0,
+			sync_strategy,
+			sync,
+			pubsub_notification_sinks,
+		)
+		.for_each(|()| futures::future::ready(())),
+	);
+
+	// Frontier `EthFilterApi` maintenance.
+	// Manages the pool of user-created Filters.
+	if let Some(eth_filter_pool) = eth_filter_pool {
+		// Each filter is allowed to stay in the pool for 100 blocks.
+		const FILTER_RETAIN_THRESHOLD: u64 = 100;
+		params.task_manager.spawn_essential_handle().spawn(
+			"frontier-filter-pool",
+			Some("frontier"),
+			EthTask::filter_pool_task(client.clone(), eth_filter_pool, FILTER_RETAIN_THRESHOLD),
+		);
+	}
+
+	// Spawn Frontier FeeHistory cache maintenance task.
+	params.task_manager.spawn_essential_handle().spawn(
+		"frontier-fee-history",
+		Some("frontier"),
+		EthTask::fee_history_task(
+			client,
+			overrides.clone(),
+			fee_history_cache,
+			fee_history_limit,
+		),
+	);
+
+	Arc::new(EthBlockDataCacheTask::new(
+		task_manager.spawn_handle(),
+		overrides,
+		50,
+		50,
+		prometheus_registry,
+	))
+}
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -14,7 +14,6 @@
 # pallet-contracts-rpc = { git = 'https://github.com/paritytech/substrate', branch = 'master' }
 pallet-transaction-payment-rpc = { workspace = true }
 sc-client-api = { workspace = true }
-sc-consensus-grandpa = { workspace = true }
 sc-network = { workspace = true }
 sc-network-sync = { workspace = true }
 sc-rpc = { workspace = true }
@@ -41,6 +40,7 @@
 up-data-structs = { workspace = true }
 up-pov-estimate-rpc = { workspace = true, default-features = true }
 up-rpc = { workspace = true }
+pallet-ethereum.workspace = true
 
 [features]
 default = []
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
before · node/rpc/src/lib.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use sp_runtime::traits::BlakeTwo256;18use fc_rpc::{19	EthBlockDataCacheTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,20	StorageOverride, SchemaV2Override, SchemaV3Override,21};22use jsonrpsee::RpcModule;23use fc_rpc_core::types::{FilterPool, FeeHistoryCache};24use fp_storage::EthereumStorageSchema;25use sc_client_api::{26	backend::{AuxStore, StorageProvider},27	client::BlockchainEvents,28	StateBackend, Backend,29};30use sc_consensus_grandpa::{31	FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,32};33use sc_network::NetworkService;34use sc_network_sync::SyncingService;35use sc_rpc::SubscriptionTaskExecutor;36pub use sc_rpc_api::DenyUnsafe;37use sc_transaction_pool::{ChainApi, Pool};38use sp_api::ProvideRuntimeApi;39use sp_block_builder::BlockBuilder;40use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};41use sc_service::TransactionPool;42use std::{collections::BTreeMap, sync::Arc};4344use up_common::types::opaque::*;4546#[cfg(feature = "pov-estimate")]47type FullBackend = sc_service::TFullBackend<Block>;4849/// Extra dependencies for GRANDPA50pub struct GrandpaDeps<B> {51	/// Voting round info.52	pub shared_voter_state: SharedVoterState,53	/// Authority set info.54	pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,55	/// Receives notifications about justification events from Grandpa.56	pub justification_stream: GrandpaJustificationStream<Block>,57	/// Executor to drive the subscription manager in the Grandpa RPC handler.58	pub subscription_executor: SubscriptionTaskExecutor,59	/// Finality proof provider.60	pub finality_provider: Arc<FinalityProofProvider<B, Block>>,61}6263/// Full client dependencies.64pub struct FullDeps<C, P, SC, CA: ChainApi> {65	/// The client instance to use.66	pub client: Arc<C>,67	/// Transaction pool instance.68	pub pool: Arc<P>,69	/// Graph pool instance.70	pub graph: Arc<Pool<CA>>,71	/// The SelectChain Strategy72	pub select_chain: SC,73	/// The Node authority flag74	pub is_authority: bool,75	/// Whether to enable dev signer76	pub enable_dev_signer: bool,77	/// Network service78	pub network: Arc<NetworkService<Block, Hash>>,79	/// Syncing service80	pub sync: Arc<SyncingService<Block>>,81	/// Whether to deny unsafe calls82	pub deny_unsafe: DenyUnsafe,83	/// EthFilterApi pool.84	pub filter_pool: Option<FilterPool>,8586	/// Runtime identification (read from the chain spec)87	pub runtime_id: RuntimeId,88	/// Executor params for PoV estimating89	#[cfg(feature = "pov-estimate")]90	pub exec_params: uc_rpc::pov_estimate::ExecutorParams,91	/// Substrate Backend.92	#[cfg(feature = "pov-estimate")]93	pub backend: Arc<FullBackend>,9495	/// Ethereum Backend.96	pub eth_backend: Arc<dyn fc_db::BackendReader<Block> + Send + Sync>,97	/// Maximum number of logs in a query.98	pub max_past_logs: u32,99	/// Maximum fee history cache size.100	pub fee_history_limit: u64,101	/// Fee history cache.102	pub fee_history_cache: FeeHistoryCache,103	/// Cache for Ethereum block data.104	pub block_data_cache: Arc<EthBlockDataCacheTask<Block>>,105106	pub pubsub_notification_sinks: Arc<107		fc_mapping_sync::EthereumBlockNotificationSinks<108			fc_mapping_sync::EthereumBlockNotification<Block>,109		>,110	>,111}112113pub fn overrides_handle<C, BE, R>(client: Arc<C>) -> Arc<OverrideHandle<Block>>114where115	C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,116	C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,117	C: Send + Sync + 'static,118	C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,119	C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,120	BE: Backend<Block> + 'static,121	BE::State: StateBackend<BlakeTwo256>,122	R: RuntimeInstance + Send + Sync + 'static,123{124	let mut overrides_map = BTreeMap::new();125	overrides_map.insert(126		EthereumStorageSchema::V1,127		Box::new(SchemaV1Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,128	);129	overrides_map.insert(130		EthereumStorageSchema::V2,131		Box::new(SchemaV2Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,132	);133	overrides_map.insert(134		EthereumStorageSchema::V3,135		Box::new(SchemaV3Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,136	);137138	Arc::new(OverrideHandle {139		schemas: overrides_map,140		fallback: Box::new(RuntimeApiStorageOverride::new(client)),141	})142}143144/// Instantiate all Full RPC extensions.145pub fn create_full<C, P, SC, CA, R, A, B>(146	deps: FullDeps<C, P, SC, CA>,147	subscription_task_executor: SubscriptionTaskExecutor,148) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>149where150	C: ProvideRuntimeApi<Block> + StorageProvider<Block, B> + AuxStore,151	C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,152	C: Send + Sync + 'static,153	C: BlockchainEvents<Block>,154	C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,155	C::Api: BlockBuilder<Block>,156	// C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,157	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,158	C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,159	C::Api: fp_rpc::ConvertTransactionRuntimeApi<Block>,160	C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,161	C::Api: app_promotion_rpc::AppPromotionApi<162		Block,163		BlockNumber,164		<R as RuntimeInstance>::CrossAccountId,165		AccountId,166	>,167	C::Api: up_pov_estimate_rpc::PovEstimateApi<Block>,168	B: sc_client_api::Backend<Block> + Send + Sync + 'static,169	B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,170	P: TransactionPool<Block = Block> + 'static,171	CA: ChainApi<Block = Block> + 'static,172	R: RuntimeInstance + Send + Sync + 'static,173	<R as RuntimeInstance>::CrossAccountId: serde::Serialize,174	C: sp_api::CallApiAt<175		sp_runtime::generic::Block<176			sp_runtime::generic::Header<u32, BlakeTwo256>,177			sp_runtime::OpaqueExtrinsic,178		>,179	>,180	for<'de> <R as RuntimeInstance>::CrossAccountId: serde::Deserialize<'de>,181{182	use fc_rpc::{183		Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub,184		EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer, TxPool, TxPoolApiServer185	};186	use uc_rpc::{UniqueApiServer, Unique};187188	use uc_rpc::{AppPromotionApiServer, AppPromotion};189190	#[cfg(feature = "pov-estimate")]191	use uc_rpc::pov_estimate::{PovEstimateApiServer, PovEstimate};192193	// use pallet_contracts_rpc::{Contracts, ContractsApi};194	use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};195	use substrate_frame_rpc_system::{System, SystemApiServer};196197	let mut io = RpcModule::new(());198	let FullDeps {199		client,200		pool,201		graph,202		select_chain: _,203		fee_history_limit,204		fee_history_cache,205		block_data_cache,206		enable_dev_signer,207		is_authority,208		network,209		sync,210		deny_unsafe,211		filter_pool,212213		runtime_id: _,214215		#[cfg(feature = "pov-estimate")]216		exec_params,217218		#[cfg(feature = "pov-estimate")]219		backend,220221		eth_backend,222		max_past_logs,223		pubsub_notification_sinks,224	} = deps;225226	io.merge(System::new(Arc::clone(&client), Arc::clone(&pool), deny_unsafe).into_rpc())?;227	io.merge(TransactionPayment::new(Arc::clone(&client)).into_rpc())?;228229	// io.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone())));230231	let mut signers = Vec::new();232	if enable_dev_signer {233		signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);234	}235236	let overrides = overrides_handle::<_, _, R>(client.clone());237238	let execute_gas_limit_multiplier = 10;239	io.merge(240		Eth::new(241			client.clone(),242			pool.clone(),243			graph.clone(),244			Some(<R as RuntimeInstance>::get_transaction_converter()),245			sync.clone(),246			signers,247			overrides.clone(),248			eth_backend.clone(),249			is_authority,250			block_data_cache.clone(),251			fee_history_cache,252			fee_history_limit,253			execute_gas_limit_multiplier,254			None,255		)256		.into_rpc(),257	)?;258259	io.merge(Unique::new(client.clone()).into_rpc())?;260261	io.merge(AppPromotion::new(client.clone()).into_rpc())?;262263	#[cfg(feature = "pov-estimate")]264	io.merge(265		PovEstimate::new(266			client.clone(),267			backend,268			deny_unsafe,269			exec_params,270			runtime_id,271		)272		.into_rpc(),273	)?;274275	let tx_pool = TxPool::new(client.clone(), graph);276	if let Some(filter_pool) = filter_pool {277		io.merge(278			EthFilter::new(279				client.clone(),280				eth_backend,281				tx_pool.clone(),282				filter_pool,283				500_usize, // max stored filters284				max_past_logs,285				block_data_cache,286			)287			.into_rpc(),288		)?;289	}290291	io.merge(292		Net::new(293			client.clone(),294			network,295			// Whether to format the `peer_count` response as Hex (default) or not.296			true,297		)298		.into_rpc(),299	)?;300301	io.merge(Web3::new(client.clone()).into_rpc())?;302303	io.merge(304		EthPubSub::new(305			pool,306			client,307			sync,308			subscription_task_executor,309			overrides,310			pubsub_notification_sinks,311		)312		.into_rpc(),313	)?;314315	io.merge(tx_pool.into_rpc())?;316317	Ok(io)318}