--- a/Cargo.lock +++ b/Cargo.lock @@ -11942,6 +11942,7 @@ "opal-runtime", "pallet-ethereum", "pallet-transaction-payment-rpc", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "parking_lot 0.11.2", "polkadot-cli", @@ -11988,7 +11989,9 @@ "substrate-prometheus-endpoint", "unique-rpc", "unique-runtime", + "unique-runtime-common", "up-data-structs", + "up-rpc", ] [[package]] @@ -12003,12 +12006,11 @@ "futures 0.3.21", "jsonrpc-core", "jsonrpc-pubsub", - "opal-runtime", + "pallet-common", "pallet-ethereum", "pallet-transaction-payment-rpc", "pallet-transaction-payment-rpc-runtime-api", "pallet-unique", - "quartz-runtime", "sc-client-api", "sc-consensus-aura", "sc-consensus-epochs", @@ -12020,6 +12022,7 @@ "sc-rpc-api", "sc-service", "sc-transaction-pool", + "serde", "sp-api", "sp-block-builder", "sp-blockchain", @@ -12034,7 +12037,7 @@ "substrate-frame-rpc-system", "tokio 0.2.25", "uc-rpc", - "unique-runtime", + "unique-runtime-common", "up-rpc", ] @@ -12118,10 +12121,13 @@ name = "unique-runtime-common" version = "0.1.0" dependencies = [ + "fp-rpc", "frame-support", "frame-system", + "pallet-common", "parity-scale-codec", "scale-info", + "sp-consensus-aura", "sp-core", "sp-runtime", ] --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -238,6 +238,10 @@ ################################################################################ # Local dependencies +[dependencies.unique-runtime-common] +default-features = false +path = "../../runtime/common" + [dependencies.unique-runtime] path = '../../runtime/unique' optional = true @@ -254,6 +258,13 @@ path = "../../primitives/data-structs" default-features = false +[dependencies.up-rpc] +path = "../../primitives/rpc" + +[dependencies.pallet-transaction-payment-rpc-runtime-api] +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + ################################################################################ # Package @@ -295,7 +306,7 @@ unique-rpc = { default-features = false, path = "../rpc" } [features] -default = ["unique-runtime"] +default = ["unique-runtime", "quartz-runtime", "opal-runtime"] runtime-benchmarks = [ 'unique-runtime/runtime-benchmarks', 'polkadot-service/runtime-benchmarks', --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -24,20 +24,33 @@ use serde::{Deserialize, Serialize}; use serde_json::map::Map; -#[cfg(feature = "unique-runtime")] -use unique_runtime as runtime; +use unique_runtime_common::types::*; -#[cfg(feature = "quartz-runtime")] -use quartz_runtime as runtime; +/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. +pub type ChainSpec = sc_service::GenericChainSpec; -#[cfg(feature = "opal-runtime")] -use opal_runtime as runtime; +pub trait RuntimeIdentification { + fn is_unique(&self) -> bool; + + fn is_quartz(&self) -> bool; -use runtime::{*, opaque::*}; + fn is_opal(&self) -> bool; +} -/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. -pub type ChainSpec = sc_service::GenericChainSpec; +impl RuntimeIdentification for Box { + fn is_unique(&self) -> bool { + self.id().starts_with("unique") + } + fn is_quartz(&self) -> bool { + self.id().starts_with("quartz") + } + + fn is_opal(&self) -> bool { + self.id().starts_with("opal") + } +} + /// Helper function to generate a crypto pair from seed pub fn get_from_seed(seed: &str) -> ::Public { TPublic::Pair::from_string(&format!("//{}", seed), None) @@ -225,10 +238,12 @@ initial_authorities: Vec, endowed_accounts: Vec, id: ParaId, -) -> GenesisConfig { +) -> unique_runtime::GenesisConfig { + use unique_runtime::*; + GenesisConfig { - system: runtime::SystemConfig { - code: runtime::WASM_BINARY + system: SystemConfig { + code: WASM_BINARY .expect("WASM binary was not build, please build it!") .to_vec(), }, @@ -245,9 +260,9 @@ key: Some(root_key), }, vesting: VestingConfig { vesting: vec![] }, - parachain_info: runtime::ParachainInfoConfig { parachain_id: id }, + parachain_info: ParachainInfoConfig { parachain_id: id }, parachain_system: Default::default(), - aura: runtime::AuraConfig { + aura: AuraConfig { authorities: initial_authorities, }, aura_ext: Default::default(), --- a/node/cli/src/command.rs +++ b/node/cli/src/command.rs @@ -33,10 +33,20 @@ // limitations under the License. use crate::{ - chain_spec, + chain_spec::{self, RuntimeIdentification}, cli::{Cli, RelayChainCli, Subcommand}, - service::{new_partial, ParachainRuntimeExecutor}, + service::new_partial, }; + +#[cfg(feature = "unique-runtime")] +use crate::service::UniqueRuntimeExecutor; + +#[cfg(feature = "quartz-runtime")] +use crate::service::QuartzRuntimeExecutor; + +#[cfg(feature = "opal-runtime")] +use crate::service::OpalRuntimeExecutor; + use codec::Encode; use cumulus_primitives_core::ParaId; use cumulus_client_service::genesis::generate_genesis_block; @@ -53,16 +63,14 @@ use sp_runtime::traits::Block as BlockT; use std::{io::Write, net::SocketAddr}; -#[cfg(feature = "unique-runtime")] -use unique_runtime as runtime; +use unique_runtime_common::types::Block; -#[cfg(feature = "quartz-runtime")] -use quartz_runtime as runtime; - -#[cfg(feature = "opal-runtime")] -use opal_runtime as runtime; - -use runtime::Block; +macro_rules! no_runtime_err { + ($chain_spec:expr) => { + format!("No runtime valid runtime was found, chain id: {}", + $chain_spec.id()) + }; +} fn load_spec(id: &str) -> std::result::Result, String> { Ok(match id { @@ -79,7 +87,7 @@ impl SubstrateCli for Cli { // TODO use args fn impl_name() -> String { - format!("{} Node", runtime::RUNTIME_NAME) + "Unique Node".into() } fn impl_version() -> String { @@ -88,11 +96,10 @@ // TODO use args fn description() -> String { format!( - "{} Node\n\nThe command-line arguments provided first will be \ + "Unique Node\n\nThe command-line arguments provided first will be \ passed to the parachain node, while the arguments provided after -- will be passed \ to the relaychain node.\n\n\ {} [parachain-args] -- [relaychain-args]", - runtime::RUNTIME_NAME, Self::executable_name() ) } @@ -114,15 +121,30 @@ load_spec(id) } - fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &runtime::VERSION + fn native_runtime_version(chain_spec: &Box) -> &'static RuntimeVersion { + #[cfg(feature = "unique-runtime")] + if chain_spec.is_unique() { + return &unique_runtime::VERSION; + } + + #[cfg(feature = "quartz-runtime")] + if chain_spec.is_quartz() { + return &quartz_runtime::VERSION; + } + + #[cfg(feature = "opal-runtime")] + if chain_spec.is_opal() { + return &opal_runtime::VERSION; + } + + panic!("{}", no_runtime_err!(chain_spec)); } } impl SubstrateCli for RelayChainCli { // TODO use args fn impl_name() -> String { - format!("{} Node", runtime::RUNTIME_NAME) + "Unique Node".into() } fn impl_version() -> String { @@ -130,13 +152,11 @@ } // TODO use args fn description() -> String { - format!( - "{} Node\n\nThe command-line arguments provided first will be \ + "Unique Node\n\nThe command-line arguments provided first will be \ passed to the parachain node, while the arguments provided after -- will be passed \ to the relaychain node.\n\n\ - parachain-collator [parachain-args] -- [relaychain-args]", - runtime::RUNTIME_NAME - ) + parachain-collator [parachain-args] -- [relaychain-args]" + .into() } fn author() -> String { @@ -173,16 +193,50 @@ macro_rules! construct_async_run { (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ let runner = $cli.create_runner($cmd)?; - runner.async_run(|$config| { - let $components = new_partial::< - _ - >( - &$config, - crate::service::parachain_build_import_queue, - )?; - let task_manager = $components.task_manager; - { $( $code )* }.map(|v| (v, task_manager)) - }) + + #[cfg(feature = "unique-runtime")] + if runner.config().chain_spec.is_unique() { + return runner.async_run(|$config| { + let $components = new_partial::< + unique_runtime::RuntimeApi, UniqueRuntimeExecutor, _ + >( + &$config, + crate::service::parachain_build_import_queue, + )?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }); + } + + #[cfg(feature = "quartz-runtime")] + if runner.config().chain_spec.is_quartz() { + return runner.async_run(|$config| { + let $components = new_partial::< + quartz_runtime::RuntimeApi, QuartzRuntimeExecutor, _ + >( + &$config, + crate::service::parachain_build_import_queue, + )?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }); + } + + #[cfg(feature = "opal-runtime")] + if runner.config().chain_spec.is_opal() { + return runner.async_run(|$config| { + let $components = new_partial::< + opal_runtime::RuntimeApi, OpalRuntimeExecutor, _ + >( + &$config, + crate::service::parachain_build_import_queue, + )?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }); + } + + Err(no_runtime_err!(runner.config().chain_spec).into()) }} } @@ -286,8 +340,24 @@ Some(Subcommand::Benchmark(cmd)) => { if cfg!(feature = "runtime-benchmarks") { let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| { + #[cfg(feature = "unique-runtime")] + if config.chain_spec.is_unique() { + return cmd.run::(config); + } + + #[cfg(feature = "quartz-runtime")] + if config.chain_spec.is_quartz() { + return cmd.run::(config); + } + + #[cfg(feature = "opal-runtime")] + if config.chain_spec.is_opal() { + return cmd.run::(config); + } - runner.sync_run(|config| cmd.run::(config)) + Err(no_runtime_err!(config.chain_spec).into()) + }) } else { Err("Benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." @@ -341,10 +411,43 @@ } ); - crate::service::start_node(config, polkadot_config, id) + #[cfg(feature = "unique-runtime")] + if config.chain_spec.is_unique() { + return crate::service::start_node::< + unique_runtime::Runtime, + unique_runtime::RuntimeApi, + UniqueRuntimeExecutor, + >(config, polkadot_config, id) .await .map(|r| r.0) - .map_err(Into::into) + .map_err(Into::into); + } + + #[cfg(feature = "quartz-runtime")] + if config.chain_spec.is_quartz() { + return crate::service::start_node::< + quartz_runtime::Runtime, + quartz_runtime::RuntimeApi, + QuartzRuntimeExecutor, + >(config, polkadot_config, id) + .await + .map(|r| r.0) + .map_err(Into::into); + } + + #[cfg(feature = "opal-runtime")] + if config.chain_spec.is_opal() { + return crate::service::start_node::< + opal_runtime::Runtime, + opal_runtime::RuntimeApi, + OpalRuntimeExecutor, + >(config, polkadot_config, id) + .await + .map(|r| r.0) + .map_err(Into::into); + } + + Err(no_runtime_err!(config.chain_spec).into()) }) } } --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -25,17 +25,8 @@ use futures::StreamExt; use unique_rpc::overrides_handle; -// Local Runtime Types -#[cfg(feature = "unique-runtime")] -use unique_runtime as runtime; - -#[cfg(feature = "quartz-runtime")] -use quartz_runtime as runtime; -#[cfg(feature = "opal-runtime")] -use opal_runtime as runtime; - -use runtime::RuntimeApi; +use serde::{Serialize, Deserialize}; // Cumulus Imports use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion}; @@ -71,18 +62,46 @@ pub type Block = sp_runtime::generic::Block; type Hash = sp_core::H256; +use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index}; + /// Native executor instance. -pub struct ParachainRuntimeExecutor; +pub struct UniqueRuntimeExecutor; +pub struct QuartzRuntimeExecutor; +pub struct OpalRuntimeExecutor; + +impl NativeExecutionDispatch for UniqueRuntimeExecutor { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + + fn dispatch(method: &str, data: &[u8]) -> Option> { + unique_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + unique_runtime::native_version() + } +} + +impl NativeExecutionDispatch for QuartzRuntimeExecutor { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; -impl NativeExecutionDispatch for ParachainRuntimeExecutor { + fn dispatch(method: &str, data: &[u8]) -> Option> { + unique_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + unique_runtime::native_version() + } +} + +impl NativeExecutionDispatch for OpalRuntimeExecutor { type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; fn dispatch(method: &str, data: &[u8]) -> Option> { - runtime::api::dispatch(method, data) + unique_runtime::api::dispatch(method, data) } fn native_version() -> sc_executor::NativeVersion { - runtime::native_version() + unique_runtime::native_version() } } @@ -106,9 +125,7 @@ )?)) } -type ExecutorDispatch = ParachainRuntimeExecutor; - -type FullClient = +type FullClient = sc_service::TFullClient>; type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; @@ -118,16 +135,16 @@ /// Use this macro if you don't actually need the full service, but just the builder in order to /// be able to perform chain operations. #[allow(clippy::type_complexity)] -pub fn new_partial( +pub fn new_partial( config: &Configuration, build_import_queue: BIQ, ) -> Result< PartialComponents< - FullClient, + FullClient, FullBackend, FullSelectChain, - sc_consensus::DefaultImportQueue, - sc_transaction_pool::FullPool, + sc_consensus::DefaultImportQueue>, + sc_transaction_pool::FullPool>, ( Option, Option, @@ -140,13 +157,21 @@ > where sc_client_api::StateBackendFor: sp_api::StateBackend, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue, ExecutorDispatch: NativeExecutionDispatch + 'static, BIQ: FnOnce( - Arc, + Arc>, &Configuration, Option, &TaskManager, - ) -> Result, sc_service::Error>, + ) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, + >, { let _telemetry = config .telemetry_endpoints @@ -240,29 +265,50 @@ /// /// This is the actual implementation that is abstract over the executor and the runtime api. #[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( +async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, id: ParaId, build_import_queue: BIQ, build_consensus: BIC, -) -> sc_service::error::Result<(TaskManager, Arc)> +) -> sc_service::error::Result<(TaskManager, Arc>)> where sc_client_api::StateBackendFor: sp_api::StateBackend, + Runtime: RuntimeInstance + Send + Sync + 'static, + ::CrossAccountId: Serialize, + for<'de> ::CrossAccountId: Deserialize<'de>, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + fp_rpc::EthereumRuntimeRPCApi + + sp_session::SessionKeys + + sp_block_builder::BlockBuilder + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::ApiExt> + + up_rpc::UniqueApi + + substrate_frame_rpc_system::AccountNonceApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + cumulus_primitives_core::CollectCollationInfo, ExecutorDispatch: NativeExecutionDispatch + 'static, BIQ: FnOnce( - Arc, + Arc>, &Configuration, Option, &TaskManager, - ) -> Result, sc_service::Error>, + ) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, + >, BIC: FnOnce( - Arc, + Arc>, Option<&Registry>, Option, &TaskManager, Arc, - Arc>, + Arc>>, Arc>, SyncCryptoStorePtr, bool, @@ -274,7 +320,8 @@ let parachain_config = prepare_node_config(parachain_config); - let params = new_partial::(¶chain_config, build_import_queue)?; + let params = + new_partial::(¶chain_config, build_import_queue)?; let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) = params.other; @@ -320,7 +367,7 @@ let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new( task_manager.spawn_handle(), - overrides_handle(client.clone()), + overrides_handle::<_, _, Runtime>(client.clone()), 50, 50, )); @@ -346,10 +393,12 @@ fee_history_limit: 2048, }; - Ok(unique_rpc::create_full::<_, _, _, _, RuntimeApi, _>( - full_deps, - subscription_executor.clone(), - )) + Ok( + unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>( + full_deps, + subscription_executor.clone(), + ), + ) }); task_manager.spawn_essential_handle().spawn( @@ -436,12 +485,26 @@ } /// Build the import queue for the the parachain runtime. -pub fn parachain_build_import_queue( - client: Arc, +pub fn parachain_build_import_queue( + client: Arc>, config: &Configuration, telemetry: Option, task_manager: &TaskManager, -) -> Result, sc_service::Error> { +) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, +> +where + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_block_builder::BlockBuilder + + sp_consensus_aura::AuraApi + + sp_api::ApiExt>, + ExecutorDispatch: NativeExecutionDispatch + 'static, +{ let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; cumulus_client_consensus_aura::import_queue::< @@ -475,12 +538,34 @@ } /// Start a normal parachain node. -pub async fn start_node( +pub async fn start_node( parachain_config: Configuration, polkadot_config: Configuration, id: ParaId, -) -> sc_service::error::Result<(TaskManager, Arc)> { - start_node_impl::<_, _>( +) -> sc_service::error::Result<(TaskManager, Arc>)> +where + Runtime: RuntimeInstance + Send + Sync + 'static, + ::CrossAccountId: Serialize, + for<'de> ::CrossAccountId: Deserialize<'de>, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + fp_rpc::EthereumRuntimeRPCApi + + sp_session::SessionKeys + + sp_block_builder::BlockBuilder + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::ApiExt> + + up_rpc::UniqueApi + + substrate_frame_rpc_system::AccountNonceApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi, + ExecutorDispatch: NativeExecutionDispatch + 'static, +{ + start_node_impl::( parachain_config, polkadot_config, id, --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -48,13 +48,16 @@ fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-common = { default-features = false, path = "../../pallets/common" } +unique-runtime-common = { default-features = false, path = "../../runtime/common" } pallet-unique = { path = "../../pallets/unique" } uc-rpc = { path = "../../client/rpc" } up-rpc = { path = "../../primitives/rpc" } -unique-runtime = { path = "../../runtime/unique", optional = true } -quartz-runtime = { path = "../../runtime/quartz", optional = true } -opal-runtime = { path = "../../runtime/opal", optional = true } +[dependencies.serde] +features = ['derive'] +version = '1.0.130' + [features] -default = ["unique-runtime"] +default = [] std = [] --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -40,16 +40,9 @@ use sc_service::TransactionPool; use std::{collections::BTreeMap, marker::PhantomData, sync::Arc}; -#[cfg(feature = "unique-runtime")] -use unique_runtime as runtime; - -#[cfg(feature = "quartz-runtime")] -use quartz_runtime as runtime; - -#[cfg(feature = "opal-runtime")] -use opal_runtime as runtime; - -use runtime::opaque::{Hash, AccountId, CrossAccountId, Index, Block, BlockNumber, Balance}; +use unique_runtime_common::types::{ + Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance, +}; /// Public io handler for exporting into other modules pub type IoHandler = jsonrpc_core::IoHandler; @@ -100,29 +93,33 @@ pub block_data_cache: Arc>, } -struct AccountCodes { +struct AccountCodes { client: Arc, - _marker: PhantomData, + _blk_marker: PhantomData, + _runtime_marker: PhantomData, } -impl AccountCodes +impl AccountCodes where Block: sp_api::BlockT, C: ProvideRuntimeApi, + R: RuntimeInstance, { fn new(client: Arc) -> Self { Self { client, - _marker: PhantomData, + _blk_marker: PhantomData, + _runtime_marker: PhantomData, } } } -impl fc_rpc::AccountCodeProvider for AccountCodes +impl fc_rpc::AccountCodeProvider for AccountCodes where Block: sp_api::BlockT, C: ProvideRuntimeApi, - C::Api: up_rpc::UniqueApi, + C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, + Runtime: RuntimeInstance, { fn code(&self, block: &sp_api::BlockId, account: sp_core::H160) -> Option> { use up_rpc::UniqueApi; @@ -134,22 +131,23 @@ } } -pub fn overrides_handle(client: Arc) -> Arc> +pub fn overrides_handle(client: Arc) -> Arc> where C: ProvideRuntimeApi + StorageProvider + AuxStore, C: HeaderBackend + HeaderMetadata, C: Send + Sync + 'static, C::Api: fp_rpc::EthereumRuntimeRPCApi, - C::Api: up_rpc::UniqueApi, + C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, BE: Backend + 'static, BE::State: StateBackend, + R: RuntimeInstance + Send + Sync + 'static, { let mut overrides_map = BTreeMap::new(); overrides_map.insert( EthereumStorageSchema::V1, Box::new(SchemaV1Override::new_with_code_provider( client.clone(), - Arc::new(AccountCodes::::new(client.clone())), + Arc::new(AccountCodes::::new(client.clone())), )) as Box + Send + Sync>, ); overrides_map.insert( @@ -170,7 +168,7 @@ } /// Instantiate all Full RPC extensions. -pub fn create_full( +pub fn create_full( deps: FullDeps, subscription_task_executor: SubscriptionTaskExecutor, ) -> jsonrpc_core::IoHandler @@ -184,11 +182,14 @@ // C::Api: pallet_contracts_rpc::ContractsRuntimeApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: fp_rpc::EthereumRuntimeRPCApi, - C::Api: up_rpc::UniqueApi, + C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, 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, + for<'de> ::CrossAccountId: serde::Deserialize<'de>, { use fc_rpc::{ EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi, @@ -235,13 +236,13 @@ signers.push(Box::new(EthDevSigner::new()) as Box); } - let overrides = overrides_handle(client.clone()); + let overrides = overrides_handle::<_, _, R>(client.clone()); io.extend_with(EthApiServer::to_delegate(EthApi::new( client.clone(), pool.clone(), graph, - runtime::TransactionConverter, + ::get_transaction_converter(), network.clone(), signers, overrides.clone(),