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
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17use fc_mapping_sync::{EthereumBlockNotificationSinks, EthereumBlockNotification};
17use sp_runtime::traits::BlakeTwo256;18use sp_runtime::traits::BlakeTwo256;
18use fc_rpc::{19use fc_rpc::{
19 EthBlockDataCacheTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,20 EthBlockDataCacheTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,
27 client::BlockchainEvents,28 client::BlockchainEvents,
28 StateBackend, Backend,29 StateBackend, Backend,
29};30};
30use sc_consensus_grandpa::{
31 FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,
32};
33use sc_network::NetworkService;31use sc_network::NetworkService;
34use sc_network_sync::SyncingService;32use sc_network_sync::SyncingService;
35use sc_rpc::SubscriptionTaskExecutor;33use sc_rpc::SubscriptionTaskExecutor;
46#[cfg(feature = "pov-estimate")]44#[cfg(feature = "pov-estimate")]
47type FullBackend = sc_service::TFullBackend<Block>;45type FullBackend = sc_service::TFullBackend<Block>;
48
49/// Extra dependencies for GRANDPA
50pub 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}
6246
63/// Full client dependencies.47/// Full client dependencies.
64pub struct FullDeps<C, P, SC, CA: ChainApi> {48pub struct FullDeps<C, P, SC> {
65 /// The client instance to use.49 /// The client instance to use.
66 pub client: Arc<C>,50 pub client: Arc<C>,
67 /// Transaction pool instance.51 /// Transaction pool instance.
68 pub pool: Arc<P>,52 pub pool: Arc<P>,
69 /// Graph pool instance.
70 pub graph: Arc<Pool<CA>>,
71 /// The SelectChain Strategy53 /// The SelectChain Strategy
72 pub select_chain: SC,54 pub select_chain: SC,
73 /// The Node authority flag
74 pub is_authority: bool,
75 /// Whether to enable dev signer
76 pub enable_dev_signer: bool,
77 /// Network service
78 pub network: Arc<NetworkService<Block, Hash>>,
79 /// Syncing service
80 pub sync: Arc<SyncingService<Block>>,
81 /// Whether to deny unsafe calls55 /// Whether to deny unsafe calls
82 pub deny_unsafe: DenyUnsafe,56 pub deny_unsafe: DenyUnsafe,
83 /// EthFilterApi pool.
84 pub filter_pool: Option<FilterPool>,
8557
86 /// Runtime identification (read from the chain spec)58 /// Runtime identification (read from the chain spec)
87 pub runtime_id: RuntimeId,59 pub runtime_id: RuntimeId,
92 #[cfg(feature = "pov-estimate")]64 #[cfg(feature = "pov-estimate")]
93 pub backend: Arc<FullBackend>,65 pub backend: Arc<FullBackend>,
94
95 /// 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>>,
105
106 pub pubsub_notification_sinks: Arc<
107 fc_mapping_sync::EthereumBlockNotificationSinks<
108 fc_mapping_sync::EthereumBlockNotification<Block>,
109 >,
110 >,
111}66}
11267
113pub fn overrides_handle<C, BE, R>(client: Arc<C>) -> Arc<OverrideHandle<Block>>68pub fn overrides_handle<C, BE, R>(client: Arc<C>) -> Arc<OverrideHandle<Block>>
141 })96 })
142}97}
14398
144/// Instantiate all Full RPC extensions.99/// Instantiate all Full RPC extensions.
100pub fn create_full<C, P, SC, R, A, B>(
101 io: &mut RpcModule<()>,
102 deps: FullDeps<C, P, SC>,
103) -> Result<(), Box<dyn std::error::Error + Send + Sync>>
104where
105 C: ProvideRuntimeApi<Block> + StorageProvider<Block, B> + AuxStore,
106 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
107 C: Send + Sync + 'static,
108 C: BlockchainEvents<Block>,
109 C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
110 C::Api: BlockBuilder<Block>,
111 // C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
112 C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
113 C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,
114 C::Api: app_promotion_rpc::AppPromotionApi<
115 Block,
116 BlockNumber,
117 <R as RuntimeInstance>::CrossAccountId,
118 AccountId,
119 >,
120 C::Api: up_pov_estimate_rpc::PovEstimateApi<Block>,
121 B: sc_client_api::Backend<Block> + Send + Sync + 'static,
122 B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
123 P: TransactionPool<Block = Block> + 'static,
124 R: RuntimeInstance + Send + Sync + 'static,
125 <R as RuntimeInstance>::CrossAccountId: serde::Serialize,
126 C: sp_api::CallApiAt<
127 sp_runtime::generic::Block<
128 sp_runtime::generic::Header<u32, BlakeTwo256>,
129 sp_runtime::OpaqueExtrinsic,
130 >,
131 >,
132 for<'de> <R as RuntimeInstance>::CrossAccountId: serde::Deserialize<'de>,
133{
134 use uc_rpc::{UniqueApiServer, Unique};
135
136 use uc_rpc::{AppPromotionApiServer, AppPromotion};
137
138 #[cfg(feature = "pov-estimate")]
139 use uc_rpc::pov_estimate::{PovEstimateApiServer, PovEstimate};
140
141 // use pallet_contracts_rpc::{Contracts, ContractsApi};
142 use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
143 use substrate_frame_rpc_system::{System, SystemApiServer};
144
145 let FullDeps {
146 client,
147 pool,
148 select_chain: _,
149 deny_unsafe,
150
151 runtime_id: _,
152
153 #[cfg(feature = "pov-estimate")]
154 exec_params,
155
156 #[cfg(feature = "pov-estimate")]
157 backend,
158 } = deps;
159
160 io.merge(System::new(Arc::clone(&client), Arc::clone(&pool), deny_unsafe).into_rpc())?;
161 io.merge(TransactionPayment::new(Arc::clone(&client)).into_rpc())?;
162
163 io.merge(Unique::new(client.clone()).into_rpc())?;
164
165 io.merge(AppPromotion::new(client.clone()).into_rpc())?;
166
167 #[cfg(feature = "pov-estimate")]
168 io.merge(
169 PovEstimate::new(
170 client.clone(),
171 backend,
172 deny_unsafe,
173 exec_params,
174 runtime_id,
175 )
176 .into_rpc(),
177 )?;
178
179 Ok(())
180}
181
182pub struct EthDeps<C, P, CA: ChainApi> {
183 /// The client instance to use.
184 pub client: Arc<C>,
185 /// Transaction pool instance.
186 pub pool: Arc<P>,
187 /// Graph pool instance.
188 pub graph: Arc<Pool<CA>>,
189 /// Syncing service
190 pub sync: Arc<SyncingService<Block>>,
191 /// The Node authority flag
192 pub is_authority: bool,
193 /// Network service
194 pub network: Arc<NetworkService<Block, Hash>>,
195
196 /// Ethereum Backend.
197 pub eth_backend: Arc<dyn fc_db::BackendReader<Block> + Send + Sync>,
198 /// Maximum number of logs in a query.
199 pub max_past_logs: u32,
200 /// Maximum fee history cache size.
201 pub fee_history_limit: u64,
202 /// Fee history cache.
203 pub fee_history_cache: FeeHistoryCache,
204 pub eth_block_data_cache: Arc<EthBlockDataCacheTask<Block>>,
205 /// EthFilterApi pool.
206 pub eth_filter_pool: Option<FilterPool>,
207 pub eth_pubsub_notification_sinks: Arc<EthereumBlockNotificationSinks<EthereumBlockNotification<Block>>>,
208 /// Whether to enable eth dev signer
209 pub enable_dev_signer: bool,
210
211 pub overrides: Arc<OverrideHandle<Block>>,
212}
213
214/// This converter is never used, but we have a generic
215/// Option<T>, where T should implement ConvertTransaction
216///
217/// TODO: remove after never-type (`!`) stabilization
218enum NeverConvert {}
219impl<T> fp_rpc::ConvertTransaction<T> for NeverConvert {
220 fn convert_transaction(&self, _transaction: pallet_ethereum::Transaction) -> T {
221 unreachable!()
222 }
223}
224
145pub fn create_full<C, P, SC, CA, R, A, B>(225pub fn create_eth<C, P, CA, B>(
226 io: &mut RpcModule<()>,
146 deps: FullDeps<C, P, SC, CA>,227 deps: EthDeps<C, P, CA>,
147 subscription_task_executor: SubscriptionTaskExecutor,228 subscription_task_executor: SubscriptionTaskExecutor,
148) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>229) -> Result<(), Box<dyn std::error::Error + Send + Sync>>
149where230where
150 C: ProvideRuntimeApi<Block> + StorageProvider<Block, B> + AuxStore,231 C: ProvideRuntimeApi<Block> + StorageProvider<Block, B> + AuxStore,
151 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,232 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
152 C: Send + Sync + 'static,233 C: Send + Sync + 'static,
153 C: BlockchainEvents<Block>,234 C: BlockchainEvents<Block>,
154 C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
155 C::Api: BlockBuilder<Block>,235 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>,236 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
159 C::Api: fp_rpc::ConvertTransactionRuntimeApi<Block>,237 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,238 P: TransactionPool<Block = Block> + 'static,
171 CA: ChainApi<Block = Block> + 'static,239 CA: ChainApi<Block = Block> + 'static,
172 R: RuntimeInstance + Send + Sync + 'static,240 B: sc_client_api::Backend<Block> + Send + Sync + 'static,
173 <R as RuntimeInstance>::CrossAccountId: serde::Serialize,
174 C: sp_api::CallApiAt<241 C: sp_api::CallApiAt<
175 sp_runtime::generic::Block<242 sp_runtime::generic::Block<
176 sp_runtime::generic::Header<u32, BlakeTwo256>,243 sp_runtime::generic::Header<u32, BlakeTwo256>,
177 sp_runtime::OpaqueExtrinsic,244 sp_runtime::OpaqueExtrinsic,
178 >,245 >,
179 >,246 >,
180 for<'de> <R as RuntimeInstance>::CrossAccountId: serde::Deserialize<'de>,
181{247{
182 use fc_rpc::{248 use fc_rpc::{
183 Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub,249 Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub,
184 EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer, TxPool, TxPoolApiServer250 EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer, TxPool, TxPoolApiServer,
185 };251 };
186 use uc_rpc::{UniqueApiServer, Unique};252
187
188 use uc_rpc::{AppPromotionApiServer, AppPromotion};
189
190 #[cfg(feature = "pov-estimate")]
191 use uc_rpc::pov_estimate::{PovEstimateApiServer, PovEstimate};
192
193 // use pallet_contracts_rpc::{Contracts, ContractsApi};
194 use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
195 use substrate_frame_rpc_system::{System, SystemApiServer};
196
197 let mut io = RpcModule::new(());
198 let FullDeps {253 let EthDeps {
199 client,254 client,
200 pool,255 pool,
201 graph,256 graph,
202 select_chain: _,257 eth_backend,
258 max_past_logs,
203 fee_history_limit,259 fee_history_limit,
204 fee_history_cache,260 fee_history_cache,
205 block_data_cache,261 eth_block_data_cache,
262 eth_filter_pool,
263 eth_pubsub_notification_sinks,
206 enable_dev_signer,264 enable_dev_signer,
265 sync,
207 is_authority,266 is_authority,
208 network,267 network,
209 sync,268 overrides,
210 deny_unsafe,
211 filter_pool,
212
213 runtime_id: _,
214
215 #[cfg(feature = "pov-estimate")]
216 exec_params,
217
218 #[cfg(feature = "pov-estimate")]
219 backend,
220
221 eth_backend,
222 max_past_logs,
223 pubsub_notification_sinks,
224 } = deps;269 } = deps;
225
226 io.merge(System::new(Arc::clone(&client), Arc::clone(&pool), deny_unsafe).into_rpc())?;
227 io.merge(TransactionPayment::new(Arc::clone(&client)).into_rpc())?;
228
229 // io.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone())));
230270
231 let mut signers = Vec::new();271 let mut signers = Vec::new();
232 if enable_dev_signer {272 if enable_dev_signer {
233 signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);273 signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
234 }274 }
235
236 let overrides = overrides_handle::<_, _, R>(client.clone());
237
238 let execute_gas_limit_multiplier = 10;275 let execute_gas_limit_multiplier = 10;
239 io.merge(276 io.merge(
240 Eth::new(277 Eth::new(
241 client.clone(),278 client.clone(),
242 pool.clone(),279 pool.clone(),
243 graph.clone(),280 graph.clone(),
281 // We have no runtimes old enough to only accept converted transactions
244 Some(<R as RuntimeInstance>::get_transaction_converter()),282 None::<NeverConvert>,
245 sync.clone(),283 sync.clone(),
246 signers,284 signers,
247 overrides.clone(),285 overrides.clone(),
248 eth_backend.clone(),286 eth_backend.clone(),
249 is_authority,287 is_authority,
250 block_data_cache.clone(),288 eth_block_data_cache.clone(),
251 fee_history_cache,289 fee_history_cache,
252 fee_history_limit,290 fee_history_limit,
253 execute_gas_limit_multiplier,291 execute_gas_limit_multiplier,
256 .into_rpc(),294 .into_rpc(),
257 )?;295 )?;
258
259 io.merge(Unique::new(client.clone()).into_rpc())?;
260
261 io.merge(AppPromotion::new(client.clone()).into_rpc())?;
262
263 #[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 )?;
274296
275 let tx_pool = TxPool::new(client.clone(), graph);297 let tx_pool = TxPool::new(
298 client.clone(),
299 graph,
300 );
301
276 if let Some(filter_pool) = filter_pool {302 if let Some(filter_pool) = eth_filter_pool {
277 io.merge(303 io.merge(
278 EthFilter::new(304 EthFilter::new(
279 client.clone(),305 client.clone(),
282 filter_pool,308 filter_pool,
283 500_usize, // max stored filters309 500_usize, // max stored filters
284 max_past_logs,310 max_past_logs,
285 block_data_cache,311 eth_block_data_cache,
286 )312 )
287 .into_rpc(),313 .into_rpc(),
288 )?;314 )?;
307 sync,330 sync,
308 subscription_task_executor,331 subscription_task_executor,
309 overrides,332 overrides,
310 pubsub_notification_sinks,333 eth_pubsub_notification_sinks,
311 )334 )
312 .into_rpc(),335 .into_rpc(),
313 )?;336 )?;
314
315 io.merge(tx_pool.into_rpc())?;337 io.merge(tx_pool.into_rpc())?;
316338
317 Ok(io)339 Ok(())
318}340}
319341