diff --git a/node/Cargo.toml b/node/Cargo.toml index 35f856a5788f992ebb5d9b0be65171c2a5eb591a..fc62d177c502f1a993b1ce4021866451d795e04b 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -30,6 +30,7 @@ constant-fees = [ ] gtest = ["gtest-runtime", "std"] embed = [] +native = [] runtime-benchmarks = [ "common-runtime/runtime-benchmarks", "dc-distance/runtime-benchmarks", diff --git a/node/src/command.rs b/node/src/command.rs index 0173cf03f01b23283029739cdfbeab1b96b2a1c7..494001e91575c66e5a3cc1106d9d0662399446a0 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -444,18 +444,22 @@ pub fn run() -> sc_cli::Result<()> { match config.chain_spec.runtime_type() { #[cfg(feature = "g1")] RuntimeType::G1 => { - service::new_full::<g1_runtime::RuntimeApi>(config, cli.sealing) + service::new_full::<g1_runtime::RuntimeApi, G1Executor>(config, cli.sealing) .map_err(sc_cli::Error::Service) } #[cfg(feature = "gtest")] - RuntimeType::GTest => { - service::new_full::<gtest_runtime::RuntimeApi>(config, cli.sealing) - .map_err(sc_cli::Error::Service) - } + RuntimeType::GTest => service::new_full::< + gtest_runtime::RuntimeApi, + GTestExecutor, + >(config, cli.sealing) + .map_err(sc_cli::Error::Service), #[cfg(feature = "gdev")] RuntimeType::GDev => { - service::new_full::<gdev_runtime::RuntimeApi>(config, cli.sealing) - .map_err(sc_cli::Error::Service) + service::new_full::<gdev_runtime::RuntimeApi, GDevExecutor>( + config, + cli.sealing, + ) + .map_err(sc_cli::Error::Service) } _ => Err(sc_cli::Error::Application("unknown runtime".into())), } diff --git a/node/src/service.rs b/node/src/service.rs index 134e7e49e1ca0596d56cc6ab06897cb2ad246c8e..3c08c188197c9850dc1c4a70d75d827a86e2b171 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -26,7 +26,6 @@ use sc_client_api::client::BlockBackend; use sc_client_api::Backend; use sc_consensus_grandpa::SharedVoterState; use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams}; -pub use sc_executor::WasmExecutor; use sc_service::WarpSyncParams; use sc_service::{error::Error as ServiceError, Configuration, PartialComponents, TaskManager}; use sc_telemetry::{Telemetry, TelemetryWorker}; @@ -43,15 +42,23 @@ type HostFunctions = ( frame_benchmarking::benchmarking::HostFunctions, ); -type FullClient<RuntimeApi> = - sc_service::TFullClient<Block, RuntimeApi, WasmExecutor<HostFunctions>>; +// Allow to use native Runtime for debugging/development purposes +#[cfg(feature = "native")] +type FullClient<RuntimeApi, Executor> = + sc_service::TFullClient<Block, RuntimeApi, sc_executor::NativeElseWasmExecutor<Executor>>; +// By default, WASM only Runtime +#[cfg(not(feature = "native"))] +type FullClient<RuntimeApi, Executor> = + sc_service::TFullClient<Block, RuntimeApi, sc_executor::WasmExecutor<Executor>>; + type FullBackend = sc_service::TFullBackend<Block>; type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>; -#[allow(dead_code)] #[cfg(feature = "gdev")] pub mod gdev_executor { + use crate::service::HostFunctions; pub use gdev_runtime; + use sc_executor::sp_wasm_interface::{Function, HostFunctionRegistry}; pub struct GDevExecutor; impl sc_executor::NativeExecutionDispatch for GDevExecutor { @@ -65,12 +72,26 @@ pub mod gdev_executor { gdev_runtime::native_version() } } + impl sc_executor::sp_wasm_interface::HostFunctions for GDevExecutor { + fn host_functions() -> Vec<&'static dyn Function> { + HostFunctions::host_functions() + } + + fn register_static<T>(registry: &mut T) -> Result<(), T::Error> + where + T: HostFunctionRegistry, + { + HostFunctions::register_static(registry) + } + } } #[allow(dead_code)] #[cfg(feature = "g1")] pub mod g1_executor { + use crate::service::HostFunctions; pub use g1_runtime; + use sc_executor::sp_wasm_interface::{Function, HostFunctionRegistry}; pub struct G1Executor; impl sc_executor::NativeExecutionDispatch for G1Executor { @@ -84,12 +105,26 @@ pub mod g1_executor { g1_runtime::native_version() } } + impl sc_executor::sp_wasm_interface::HostFunctions for G1Executor { + fn host_functions() -> Vec<&'static dyn Function> { + HostFunctions::host_functions() + } + + fn register_static<T>(registry: &mut T) -> Result<(), T::Error> + where + T: HostFunctionRegistry, + { + HostFunctions::register_static(registry) + } + } } #[allow(dead_code)] #[cfg(feature = "gtest")] pub mod gtest_executor { + use crate::service::HostFunctions; pub use gtest_runtime; + use sc_executor::sp_wasm_interface::{Function, HostFunctionRegistry}; pub struct GTestExecutor; impl sc_executor::NativeExecutionDispatch for GTestExecutor { @@ -103,6 +138,18 @@ pub mod gtest_executor { gtest_runtime::native_version() } } + impl sc_executor::sp_wasm_interface::HostFunctions for GTestExecutor { + fn host_functions() -> Vec<&'static dyn Function> { + HostFunctions::host_functions() + } + + fn register_static<T>(registry: &mut T) -> Result<(), T::Error> + where + T: HostFunctionRegistry, + { + HostFunctions::register_static(registry) + } + } } /// /// The minimum period of blocks on which justifications will be @@ -160,7 +207,10 @@ pub fn new_chain_ops( import_queue, task_manager, .. - } = new_partial::<g1_runtime::RuntimeApi>(config, manual_consensus)?; + } = new_partial::<g1_runtime::RuntimeApi, g1_executor::G1Executor>( + config, + manual_consensus, + )?; Ok(( Arc::new(Client::G1(client)), backend, @@ -176,7 +226,10 @@ pub fn new_chain_ops( import_queue, task_manager, .. - } = new_partial::<gtest_runtime::RuntimeApi>(config, manual_consensus)?; + } = new_partial::<gtest_runtime::RuntimeApi, gtest_executor::GTestExecutor>( + config, + manual_consensus, + )?; Ok(( Arc::new(Client::GTest(client)), backend, @@ -192,7 +245,10 @@ pub fn new_chain_ops( import_queue, task_manager, .. - } = new_partial::<gdev_runtime::RuntimeApi>(config, manual_consensus)?; + } = new_partial::<gdev_runtime::RuntimeApi, gdev_executor::GDevExecutor>( + config, + manual_consensus, + )?; Ok(( Arc::new(Client::GDev(client)), backend, @@ -204,41 +260,50 @@ pub fn new_chain_ops( } } -type FullGrandpaBlockImport<RuntimeApi> = sc_consensus_grandpa::GrandpaBlockImport< +type FullGrandpaBlockImport<RuntimeApi, Executor> = sc_consensus_grandpa::GrandpaBlockImport< FullBackend, Block, - FullClient<RuntimeApi>, + FullClient<RuntimeApi, Executor>, FullSelectChain, >; #[allow(clippy::type_complexity)] -pub fn new_partial<RuntimeApi>( +pub fn new_partial<RuntimeApi, Executor>( config: &Configuration, consensus_manual: bool, ) -> Result< sc_service::PartialComponents< - FullClient<RuntimeApi>, + FullClient<RuntimeApi, Executor>, FullBackend, FullSelectChain, sc_consensus::DefaultImportQueue<Block>, - sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi>>, + sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, Executor>>, ( sc_consensus_babe::BabeBlockImport< Block, - FullClient<RuntimeApi>, - FullGrandpaBlockImport<RuntimeApi>, + FullClient<RuntimeApi, Executor>, + FullGrandpaBlockImport<RuntimeApi, Executor>, >, sc_consensus_babe::BabeLink<Block>, Option<sc_consensus_babe::BabeWorkerHandle<Block>>, - sc_consensus_grandpa::LinkHalf<Block, FullClient<RuntimeApi>, FullSelectChain>, + sc_consensus_grandpa::LinkHalf< + Block, + FullClient<RuntimeApi, Executor>, + FullSelectChain, + >, Option<Telemetry>, ), >, ServiceError, > where - RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi>> + Send + Sync + 'static, + RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, Executor>> + + Send + + Sync + + 'static, RuntimeApi::RuntimeApi: RuntimeApiCollection, + Executor: sc_executor::NativeExecutionDispatch + 'static, + Executor: sc_executor::sp_wasm_interface::HostFunctions + 'static, { let telemetry = config .telemetry_endpoints @@ -251,6 +316,9 @@ where }) .transpose()?; + #[cfg(feature = "native")] + let executor = sc_service::new_native_or_wasm_executor(config); + #[cfg(not(feature = "native"))] let executor = sc_service::new_wasm_executor(config); let (client, backend, keystore_container, task_manager) = @@ -353,13 +421,18 @@ where } /// Builds a new service for a full client. -pub fn new_full<RuntimeApi>( +pub fn new_full<RuntimeApi, Executor>( config: Configuration, sealing: crate::cli::Sealing, ) -> Result<TaskManager, ServiceError> where - RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi>> + Send + Sync + 'static, + RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, Executor>> + + Send + + Sync + + 'static, RuntimeApi::RuntimeApi: RuntimeApiCollection, + Executor: sc_executor::NativeExecutionDispatch + 'static, + Executor: sc_executor::sp_wasm_interface::HostFunctions + 'static, { let sc_service::PartialComponents { client, @@ -370,7 +443,7 @@ where select_chain, transaction_pool, other: (block_import, babe_link, babe_worker_handle, grandpa_link, mut telemetry), - } = new_partial::<RuntimeApi>(&config, sealing.is_manual_consensus())?; + } = new_partial::<RuntimeApi, Executor>(&config, sealing.is_manual_consensus())?; let grandpa_protocol_name = sc_consensus_grandpa::protocol_standard_name( &client @@ -536,7 +609,7 @@ where let distance = dc_distance::create_distance_inherent_data_provider::< Block, - FullClient<RuntimeApi>, + FullClient<RuntimeApi, Executor>, FullBackend, >( &*client, parent, distance_dir, &babe_owner_keys.clone() @@ -583,7 +656,7 @@ where let distance = dc_distance::create_distance_inherent_data_provider::< Block, - FullClient<RuntimeApi>, + FullClient<RuntimeApi, Executor>, FullBackend, >( &*client, parent, distance_dir, &babe_owner_keys.clone() diff --git a/node/src/service/client.rs b/node/src/service/client.rs index 1faebeb6c44fd4561bf23621b43e147745cad237..cad8ce1d679a92cfef21b17774c69d6832294d99 100644 --- a/node/src/service/client.rs +++ b/node/src/service/client.rs @@ -146,11 +146,11 @@ impl<Api> RuntimeApiCollection for Api where #[derive(Clone)] pub enum Client { #[cfg(feature = "g1")] - G1(Arc<super::FullClient<g1_runtime::RuntimeApi>>), + G1(Arc<super::FullClient<g1_runtime::RuntimeApi, super::g1_executor::G1Executor>>), #[cfg(feature = "gtest")] - GTest(Arc<super::FullClient<gtest_runtime::RuntimeApi>>), + GTest(Arc<super::FullClient<gtest_runtime::RuntimeApi, super::gtest_executor::GTestExecutor>>), #[cfg(feature = "gdev")] - GDev(Arc<super::FullClient<gdev_runtime::RuntimeApi>>), + GDev(Arc<super::FullClient<gdev_runtime::RuntimeApi, super::gdev_executor::GDevExecutor>>), } macro_rules! with_client { @@ -197,22 +197,38 @@ impl ClientHandle for Client { } #[cfg(feature = "g1")] -impl From<Arc<super::FullClient<g1_runtime::RuntimeApi>>> for Client { - fn from(client: Arc<super::FullClient<g1_runtime::RuntimeApi>>) -> Self { +impl From<Arc<super::FullClient<g1_runtime::RuntimeApi, super::g1_executor::G1Executor>>> + for Client +{ + fn from( + client: Arc<super::FullClient<g1_runtime::RuntimeApi, super::g1_executor::G1Executor>>, + ) -> Self { Self::G1(client) } } #[cfg(feature = "gtest")] -impl From<Arc<super::FullClient<gtest_runtime::RuntimeApi>>> for Client { - fn from(client: Arc<super::FullClient<gtest_runtime::RuntimeApi>>) -> Self { +impl From<Arc<super::FullClient<gtest_runtime::RuntimeApi, super::gtest_executor::GTestExecutor>>> + for Client +{ + fn from( + client: Arc< + super::FullClient<gtest_runtime::RuntimeApi, super::gtest_executor::GTestExecutor>, + >, + ) -> Self { Self::GTest(client) } } #[cfg(feature = "gdev")] -impl From<Arc<super::FullClient<gdev_runtime::RuntimeApi>>> for Client { - fn from(client: Arc<super::FullClient<gdev_runtime::RuntimeApi>>) -> Self { +impl From<Arc<super::FullClient<gdev_runtime::RuntimeApi, super::gdev_executor::GDevExecutor>>> + for Client +{ + fn from( + client: Arc< + super::FullClient<gdev_runtime::RuntimeApi, super::gdev_executor::GDevExecutor>, + >, + ) -> Self { Self::GDev(client) } } @@ -311,14 +327,16 @@ trait BenchmarkCallSigner<RuntimeCall: Encode + Clone, Signer: Pair> { #[cfg(feature = "g1")] use g1_runtime as runtime; +#[cfg(feature = "g1")] +type FullClient = super::FullClient<runtime::RuntimeApi, super::g1_executor::G1Executor>; #[cfg(feature = "gdev")] use gdev_runtime as runtime; #[cfg(feature = "gdev")] -type FullClient = super::FullClient<runtime::RuntimeApi>; +type FullClient = super::FullClient<runtime::RuntimeApi, super::gdev_executor::GDevExecutor>; #[cfg(feature = "gtest")] use gtest_runtime as runtime; #[cfg(feature = "gtest")] -type FullClient = super::FullClient<runtime::RuntimeApi>; +type FullClient = super::FullClient<runtime::RuntimeApi, super::gtest_executor::GTestExecutor>; #[cfg(any(feature = "gdev", feature = "gtest"))] impl BenchmarkCallSigner<runtime::RuntimeCall, sp_core::sr25519::Pair> for FullClient {