--- 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", --- 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" } --- 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 } --- 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 --- 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>( +pub fn open_frontier_backend>( client: Arc, config: &Configuration, ) -> Result>, String> { @@ -213,13 +225,7 @@ FullSelectChain, sc_consensus::DefaultImportQueue>, sc_transaction_pool::FullPool>, - ( - Option, - Option, - Arc>, - Option, - 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 = Some(Arc::new(Mutex::new(BTreeMap::new()))); + let eth_filter_pool: Option = 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::(¶chain_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(¶chain_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, + // Frontier + let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new())); + let fee_history_limit = 2048; + + let eth_pubsub_notification_sinks: Arc< + EthereumBlockNotificationSinks>, > = 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, + pub telemetry_worker_handle: Option, + pub eth_filter_pool: Option, + pub eth_backend: Arc>, +} + /// Builds a new development service. This service uses instant seal, and mocks /// the parachain inherent pub fn start_dev_node( @@ -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::( &config, dev_build_import_queue::, @@ -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, - > = 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>, + > = 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(client: Arc) -> Arc> +where + C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata, + C: Send + Sync + 'static, + C::Api: fp_rpc::EthereumRuntimeRPCApi, + BE: Backend + 'static, + BE::State: StateBackend, +{ + let mut overrides_map = BTreeMap::new(); + overrides_map.insert( + EthereumStorageSchema::V1, + Box::new(SchemaV1Override::new(client.clone())) as Box + 'static>, + ); + overrides_map.insert( + EthereumStorageSchema::V2, + Box::new(SchemaV2Override::new(client.clone())) as Box + 'static>, + ); + overrides_map.insert( + EthereumStorageSchema::V3, + Box::new(SchemaV3Override::new(client.clone())) as Box + '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, + pub substrate_backend: Arc, + pub eth_backend: Arc>, + pub eth_filter_pool: Option, + pub overrides: Arc>, + pub fee_history_limit: u64, + pub fee_history_cache: FeeHistoryCache, + pub sync_strategy: SyncStrategy, + pub prometheus_registry: Option, +} + +pub fn spawn_frontier_tasks( + params: FrontierTaskParams, + sync: Arc>, + pubsub_notification_sinks: Arc< + EthereumBlockNotificationSinks>, + >, +) -> Arc> +where + C: ProvideRuntimeApi + BlockOf, + C: HeaderBackend + HeaderMetadata + 'static, + C: BlockchainEvents + StorageProvider, + C: Send + Sync + 'static, + C::Api: EthereumRuntimeRPCApi, + C::Api: BlockBuilder, + B: BlockT + Send + Sync + 'static, + B::Header: HeaderT, + BE: Backend + 'static, + BE::State: StateBackend, +{ + 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, + )) +} --- 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 = [] --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . +use fc_mapping_sync::{EthereumBlockNotificationSinks, EthereumBlockNotification}; use sp_runtime::traits::BlakeTwo256; use fc_rpc::{ EthBlockDataCacheTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override, @@ -26,9 +27,6 @@ backend::{AuxStore, StorageProvider}, client::BlockchainEvents, StateBackend, Backend, -}; -use sc_consensus_grandpa::{ - FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState, }; use sc_network::NetworkService; use sc_network_sync::SyncingService; @@ -46,42 +44,16 @@ #[cfg(feature = "pov-estimate")] type FullBackend = sc_service::TFullBackend; -/// Extra dependencies for GRANDPA -pub struct GrandpaDeps { - /// Voting round info. - pub shared_voter_state: SharedVoterState, - /// Authority set info. - pub shared_authority_set: SharedAuthoritySet, - /// Receives notifications about justification events from Grandpa. - pub justification_stream: GrandpaJustificationStream, - /// Executor to drive the subscription manager in the Grandpa RPC handler. - pub subscription_executor: SubscriptionTaskExecutor, - /// Finality proof provider. - pub finality_provider: Arc>, -} - /// Full client dependencies. -pub struct FullDeps { +pub struct FullDeps { /// The client instance to use. pub client: Arc, /// Transaction pool instance. pub pool: Arc

, - /// Graph pool instance. - pub graph: Arc>, /// The SelectChain Strategy pub select_chain: SC, - /// The Node authority flag - pub is_authority: bool, - /// Whether to enable dev signer - pub enable_dev_signer: bool, - /// Network service - pub network: Arc>, - /// Syncing service - pub sync: Arc>, /// Whether to deny unsafe calls pub deny_unsafe: DenyUnsafe, - /// EthFilterApi pool. - pub filter_pool: Option, /// Runtime identification (read from the chain spec) pub runtime_id: RuntimeId, @@ -91,23 +63,6 @@ /// Substrate Backend. #[cfg(feature = "pov-estimate")] pub backend: Arc, - - /// Ethereum Backend. - pub eth_backend: Arc + Send + Sync>, - /// Maximum number of logs in a query. - pub max_past_logs: u32, - /// Maximum fee history cache size. - pub fee_history_limit: u64, - /// Fee history cache. - pub fee_history_cache: FeeHistoryCache, - /// Cache for Ethereum block data. - pub block_data_cache: Arc>, - - pub pubsub_notification_sinks: Arc< - fc_mapping_sync::EthereumBlockNotificationSinks< - fc_mapping_sync::EthereumBlockNotification, - >, - >, } pub fn overrides_handle(client: Arc) -> Arc> @@ -142,10 +97,10 @@ } /// Instantiate all Full RPC extensions. -pub fn create_full( - deps: FullDeps, - subscription_task_executor: SubscriptionTaskExecutor, -) -> Result, Box> +pub fn create_full( + io: &mut RpcModule<()>, + deps: FullDeps, +) -> Result<(), Box> where C: ProvideRuntimeApi + StorageProvider + AuxStore, C: HeaderBackend + HeaderMetadata + 'static, @@ -155,8 +110,6 @@ C::Api: BlockBuilder, // C::Api: pallet_contracts_rpc::ContractsRuntimeApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - C::Api: fp_rpc::EthereumRuntimeRPCApi, - C::Api: fp_rpc::ConvertTransactionRuntimeApi, C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, C::Api: app_promotion_rpc::AppPromotionApi< Block, @@ -168,7 +121,6 @@ B: sc_client_api::Backend + Send + Sync + 'static, B::State: sc_client_api::backend::StateBackend>, P: TransactionPool + 'static, - CA: ChainApi + 'static, R: RuntimeInstance + Send + Sync + 'static, ::CrossAccountId: serde::Serialize, C: sp_api::CallApiAt< @@ -179,10 +131,6 @@ >, for<'de> ::CrossAccountId: serde::Deserialize<'de>, { - use fc_rpc::{ - Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub, - EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer, TxPool, TxPoolApiServer - }; use uc_rpc::{UniqueApiServer, Unique}; use uc_rpc::{AppPromotionApiServer, AppPromotion}; @@ -194,21 +142,11 @@ use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; - let mut io = RpcModule::new(()); let FullDeps { client, pool, - graph, select_chain: _, - fee_history_limit, - fee_history_cache, - block_data_cache, - enable_dev_signer, - is_authority, - network, - sync, deny_unsafe, - filter_pool, runtime_id: _, @@ -217,37 +155,137 @@ #[cfg(feature = "pov-estimate")] backend, - - eth_backend, - max_past_logs, - pubsub_notification_sinks, } = deps; io.merge(System::new(Arc::clone(&client), Arc::clone(&pool), deny_unsafe).into_rpc())?; io.merge(TransactionPayment::new(Arc::clone(&client)).into_rpc())?; - // io.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone()))); + io.merge(Unique::new(client.clone()).into_rpc())?; + + io.merge(AppPromotion::new(client.clone()).into_rpc())?; + + #[cfg(feature = "pov-estimate")] + io.merge( + PovEstimate::new( + client.clone(), + backend, + deny_unsafe, + exec_params, + runtime_id, + ) + .into_rpc(), + )?; + + Ok(()) +} + +pub struct EthDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Graph pool instance. + pub graph: Arc>, + /// Syncing service + pub sync: Arc>, + /// The Node authority flag + pub is_authority: bool, + /// Network service + pub network: Arc>, + + /// Ethereum Backend. + pub eth_backend: Arc + Send + Sync>, + /// Maximum number of logs in a query. + pub max_past_logs: u32, + /// Maximum fee history cache size. + pub fee_history_limit: u64, + /// Fee history cache. + pub fee_history_cache: FeeHistoryCache, + pub eth_block_data_cache: Arc>, + /// EthFilterApi pool. + pub eth_filter_pool: Option, + pub eth_pubsub_notification_sinks: Arc>>, + /// Whether to enable eth dev signer + pub enable_dev_signer: bool, + + pub overrides: Arc>, +} + +/// This converter is never used, but we have a generic +/// Option, where T should implement ConvertTransaction +/// +/// TODO: remove after never-type (`!`) stabilization +enum NeverConvert {} +impl fp_rpc::ConvertTransaction for NeverConvert { + fn convert_transaction(&self, _transaction: pallet_ethereum::Transaction) -> T { + unreachable!() + } +} +pub fn create_eth( + io: &mut RpcModule<()>, + deps: EthDeps, + subscription_task_executor: SubscriptionTaskExecutor, +) -> Result<(), Box> +where + C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, + C: Send + Sync + 'static, + C: BlockchainEvents, + C::Api: BlockBuilder, + C::Api: fp_rpc::EthereumRuntimeRPCApi, + C::Api: fp_rpc::ConvertTransactionRuntimeApi, + P: TransactionPool + 'static, + CA: ChainApi + 'static, + B: sc_client_api::Backend + Send + Sync + 'static, + C: sp_api::CallApiAt< + sp_runtime::generic::Block< + sp_runtime::generic::Header, + sp_runtime::OpaqueExtrinsic, + >, + >, +{ + use fc_rpc::{ + Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub, + EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer, TxPool, TxPoolApiServer, + }; + + let EthDeps { + client, + pool, + graph, + eth_backend, + max_past_logs, + fee_history_limit, + fee_history_cache, + eth_block_data_cache, + eth_filter_pool, + eth_pubsub_notification_sinks, + enable_dev_signer, + sync, + is_authority, + network, + overrides, + } = deps; + let mut signers = Vec::new(); if enable_dev_signer { signers.push(Box::new(EthDevSigner::new()) as Box); } - - let overrides = overrides_handle::<_, _, R>(client.clone()); - let execute_gas_limit_multiplier = 10; io.merge( Eth::new( client.clone(), pool.clone(), graph.clone(), - Some(::get_transaction_converter()), + // We have no runtimes old enough to only accept converted transactions + None::, sync.clone(), signers, overrides.clone(), eth_backend.clone(), is_authority, - block_data_cache.clone(), + eth_block_data_cache.clone(), fee_history_cache, fee_history_limit, execute_gas_limit_multiplier, @@ -256,24 +294,12 @@ .into_rpc(), )?; - io.merge(Unique::new(client.clone()).into_rpc())?; - - io.merge(AppPromotion::new(client.clone()).into_rpc())?; + let tx_pool = TxPool::new( + client.clone(), + graph, + ); - #[cfg(feature = "pov-estimate")] - io.merge( - PovEstimate::new( - client.clone(), - backend, - deny_unsafe, - exec_params, - runtime_id, - ) - .into_rpc(), - )?; - - let tx_pool = TxPool::new(client.clone(), graph); - if let Some(filter_pool) = filter_pool { + if let Some(filter_pool) = eth_filter_pool { io.merge( EthFilter::new( client.clone(), @@ -282,12 +308,11 @@ filter_pool, 500_usize, // max stored filters max_past_logs, - block_data_cache, + eth_block_data_cache, ) .into_rpc(), )?; } - io.merge( Net::new( client.clone(), @@ -297,9 +322,7 @@ ) .into_rpc(), )?; - io.merge(Web3::new(client.clone()).into_rpc())?; - io.merge( EthPubSub::new( pool, @@ -307,12 +330,11 @@ sync, subscription_task_executor, overrides, - pubsub_notification_sinks, + eth_pubsub_notification_sinks, ) .into_rpc(), )?; - io.merge(tx_pool.into_rpc())?; - Ok(io) + Ok(()) }