diff --git a/Cargo.lock b/Cargo.lock
index 590c800cc9bf..2e822a3100ce 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13865,6 +13865,102 @@ dependencies = [
]
[[package]]
+<<<<<<< HEAD
+=======
+name = "polkadot-omni-node"
+version = "0.1.0"
+dependencies = [
+ "color-eyre",
+ "polkadot-omni-node-lib",
+ "substrate-build-script-utils",
+]
+
+[[package]]
+name = "polkadot-omni-node-lib"
+version = "0.1.0"
+dependencies = [
+ "assert_cmd",
+ "async-trait",
+ "clap 4.5.13",
+ "color-print",
+ "cumulus-client-cli",
+ "cumulus-client-collator",
+ "cumulus-client-consensus-aura",
+ "cumulus-client-consensus-common",
+ "cumulus-client-consensus-proposer",
+ "cumulus-client-consensus-relay-chain",
+ "cumulus-client-parachain-inherent",
+ "cumulus-client-service",
+ "cumulus-primitives-aura 0.7.0",
+ "cumulus-primitives-core 0.7.0",
+ "cumulus-relay-chain-interface",
+ "cumulus-test-runtime",
+ "docify",
+ "frame-benchmarking 28.0.0",
+ "frame-benchmarking-cli",
+ "frame-support 28.0.0",
+ "frame-system-rpc-runtime-api 26.0.0",
+ "frame-try-runtime 0.34.0",
+ "futures",
+ "futures-timer",
+ "jsonrpsee",
+ "log",
+ "nix 0.29.0",
+ "pallet-transaction-payment 28.0.0",
+ "pallet-transaction-payment-rpc",
+ "pallet-transaction-payment-rpc-runtime-api 28.0.0",
+ "parachains-common 7.0.0",
+ "parity-scale-codec",
+ "polkadot-cli",
+ "polkadot-primitives 7.0.0",
+ "sc-basic-authorship",
+ "sc-chain-spec",
+ "sc-cli",
+ "sc-client-api",
+ "sc-client-db",
+ "sc-consensus",
+ "sc-consensus-manual-seal",
+ "sc-executor 0.32.0",
+ "sc-network",
+ "sc-offchain",
+ "sc-rpc",
+ "sc-runtime-utilities",
+ "sc-service",
+ "sc-sysinfo",
+ "sc-telemetry",
+ "sc-tracing",
+ "sc-transaction-pool",
+ "sc-transaction-pool-api",
+ "scale-info",
+ "serde",
+ "serde_json",
+ "sp-api 26.0.0",
+ "sp-block-builder 26.0.0",
+ "sp-consensus",
+ "sp-consensus-aura 0.32.0",
+ "sp-core 28.0.0",
+ "sp-crypto-hashing 0.1.0",
+ "sp-genesis-builder 0.8.0",
+ "sp-inherents 26.0.0",
+ "sp-keystore 0.34.0",
+ "sp-offchain 26.0.0",
+ "sp-runtime 31.0.1",
+ "sp-session 27.0.0",
+ "sp-storage 19.0.0",
+ "sp-timestamp 26.0.0",
+ "sp-transaction-pool 26.0.0",
+ "sp-version 29.0.0",
+ "sp-weights 27.0.0",
+ "substrate-frame-rpc-system",
+ "substrate-prometheus-endpoint",
+ "substrate-state-trie-migration-rpc",
+ "subxt-metadata",
+ "tokio",
+ "wait-timeout",
+]
+
+[[package]]
+>>>>>>> 87f4f3f0 (omni-node: add offchain worker (#7479))
name = "polkadot-overseer"
version = "18.0.0"
dependencies = [
diff --git a/cumulus/polkadot-omni-node/lib/Cargo.toml b/cumulus/polkadot-omni-node/lib/Cargo.toml
new file mode 100644
index 000000000000..020d980d3d9d
--- /dev/null
+++ b/cumulus/polkadot-omni-node/lib/Cargo.toml
@@ -0,0 +1,130 @@
+[package]
+name = "polkadot-omni-node-lib"
+version = "0.1.0"
+authors.workspace = true
+edition.workspace = true
+description = "Helper library that can be used to build a parachain node"
+license = "Apache-2.0"
+homepage.workspace = true
+repository.workspace = true
+
+[lints]
+workspace = true
+
+[lib]
+path = "src/lib.rs"
+
+[dependencies]
+async-trait = { workspace = true }
+clap = { features = ["derive"], workspace = true }
+codec = { workspace = true, default-features = true }
+color-print = { workspace = true }
+docify = { workspace = true }
+futures = { workspace = true }
+log = { workspace = true, default-features = true }
+serde = { features = ["derive"], workspace = true, default-features = true }
+serde_json = { workspace = true, default-features = true }
+
+# Local
+jsonrpsee = { features = ["server"], workspace = true }
+parachains-common = { workspace = true, default-features = true }
+scale-info = { workspace = true }
+subxt-metadata = { workspace = true, default-features = true }
+
+# Substrate
+frame-benchmarking = { optional = true, workspace = true, default-features = true }
+frame-benchmarking-cli = { workspace = true, default-features = true }
+frame-support = { optional = true, workspace = true, default-features = true }
+frame-system-rpc-runtime-api = { workspace = true, default-features = true }
+frame-try-runtime = { optional = true, workspace = true, default-features = true }
+pallet-transaction-payment = { workspace = true, default-features = true }
+pallet-transaction-payment-rpc = { workspace = true, default-features = true }
+pallet-transaction-payment-rpc-runtime-api = { workspace = true, default-features = true }
+prometheus-endpoint = { workspace = true, default-features = true }
+sc-basic-authorship = { workspace = true, default-features = true }
+sc-chain-spec = { workspace = true, default-features = true }
+sc-cli = { workspace = true, default-features = true }
+sc-client-api = { workspace = true, default-features = true }
+sc-client-db = { workspace = true, default-features = true }
+sc-consensus = { workspace = true, default-features = true }
+sc-consensus-manual-seal = { workspace = true, default-features = true }
+sc-executor = { workspace = true, default-features = true }
+sc-network = { workspace = true, default-features = true }
+sc-offchain = { workspace = true, default-features = true }
+sc-rpc = { workspace = true, default-features = true }
+sc-runtime-utilities = { workspace = true, default-features = true }
+sc-service = { workspace = true, default-features = true }
+sc-sysinfo = { workspace = true, default-features = true }
+sc-telemetry = { workspace = true, default-features = true }
+sc-tracing = { workspace = true, default-features = true }
+sc-transaction-pool = { workspace = true, default-features = true }
+sc-transaction-pool-api = { workspace = true, default-features = true }
+sp-api = { workspace = true, default-features = true }
+sp-block-builder = { workspace = true, default-features = true }
+sp-consensus = { workspace = true, default-features = true }
+sp-consensus-aura = { workspace = true, default-features = true }
+sp-core = { workspace = true, default-features = true }
+sp-crypto-hashing = { workspace = true }
+sp-genesis-builder = { workspace = true }
+sp-inherents = { workspace = true, default-features = true }
+sp-keystore = { workspace = true, default-features = true }
+sp-offchain = { workspace = true, default-features = true }
+sp-runtime = { workspace = true }
+sp-session = { workspace = true, default-features = true }
+sp-storage = { workspace = true, default-features = true }
+sp-timestamp = { workspace = true, default-features = true }
+sp-transaction-pool = { workspace = true, default-features = true }
+sp-version = { workspace = true, default-features = true }
+sp-weights = { workspace = true, default-features = true }
+substrate-frame-rpc-system = { workspace = true, default-features = true }
+substrate-state-trie-migration-rpc = { workspace = true, default-features = true }
+
+# Polkadot
+polkadot-cli = { workspace = true, default-features = true }
+polkadot-primitives = { workspace = true, default-features = true }
+
+# Cumulus
+cumulus-client-cli = { workspace = true, default-features = true }
+cumulus-client-collator = { workspace = true, default-features = true }
+cumulus-client-consensus-aura = { workspace = true, default-features = true }
+cumulus-client-consensus-common = { workspace = true, default-features = true }
+cumulus-client-consensus-proposer = { workspace = true, default-features = true }
+cumulus-client-consensus-relay-chain = { workspace = true, default-features = true }
+cumulus-client-parachain-inherent = { workspace = true, default-features = true }
+cumulus-client-service = { workspace = true, default-features = true }
+cumulus-primitives-aura = { workspace = true, default-features = true }
+cumulus-primitives-core = { workspace = true, default-features = true }
+cumulus-relay-chain-interface = { workspace = true, default-features = true }
+futures-timer = "3.0.3"
+
+[dev-dependencies]
+assert_cmd = { workspace = true }
+cumulus-test-runtime = { workspace = true }
+nix = { features = ["signal"], workspace = true }
+tokio = { version = "1.32.0", features = ["macros", "parking_lot", "time"] }
+wait-timeout = { workspace = true }
+
+[features]
+default = []
+rococo-native = ["polkadot-cli/rococo-native"]
+westend-native = ["polkadot-cli/westend-native"]
+runtime-benchmarks = [
+ "cumulus-primitives-core/runtime-benchmarks",
+ "frame-benchmarking-cli/runtime-benchmarks",
+ "frame-benchmarking/runtime-benchmarks",
+ "frame-support/runtime-benchmarks",
+ "pallet-transaction-payment/runtime-benchmarks",
+ "parachains-common/runtime-benchmarks",
+ "polkadot-cli/runtime-benchmarks",
+ "polkadot-primitives/runtime-benchmarks",
+ "sc-client-db/runtime-benchmarks",
+ "sc-service/runtime-benchmarks",
+ "sp-runtime/runtime-benchmarks",
+]
+try-runtime = [
+ "frame-support/try-runtime",
+ "frame-try-runtime/try-runtime",
+ "pallet-transaction-payment/try-runtime",
+ "polkadot-cli/try-runtime",
+ "sp-runtime/try-runtime",
+]
diff --git a/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs b/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs
new file mode 100644
index 000000000000..96802177ec10
--- /dev/null
+++ b/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs
@@ -0,0 +1,287 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus. If not, see .
+
+use crate::common::{
+ rpc::BuildRpcExtensions as BuildRpcExtensionsT,
+ spec::{BaseNodeSpec, BuildImportQueue, ClientBlockImport, NodeSpec as NodeSpecT},
+ types::{Hash, ParachainBlockImport, ParachainClient},
+};
+use codec::Encode;
+use cumulus_client_parachain_inherent::{MockValidationDataInherentDataProvider, MockXcmConfig};
+use cumulus_primitives_aura::AuraUnincludedSegmentApi;
+use cumulus_primitives_core::{CollectCollationInfo, ParaId};
+use futures::FutureExt;
+use polkadot_primitives::UpgradeGoAhead;
+use sc_client_api::Backend;
+use sc_consensus::{DefaultImportQueue, LongestChain};
+use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer};
+use sc_network::NetworkBackend;
+use sc_service::{Configuration, PartialComponents, TaskManager};
+use sc_telemetry::TelemetryHandle;
+use sc_transaction_pool_api::OffchainTransactionPoolFactory;
+use sp_api::{ApiExt, ProvideRuntimeApi};
+use sp_runtime::traits::Header;
+use std::{marker::PhantomData, sync::Arc};
+
+pub struct ManualSealNode(PhantomData);
+
+impl
+ BuildImportQueue<
+ NodeSpec::Block,
+ NodeSpec::RuntimeApi,
+ Arc>,
+ > for ManualSealNode
+{
+ fn build_import_queue(
+ client: Arc>,
+ _block_import: ParachainBlockImport<
+ NodeSpec::Block,
+ Arc>,
+ >,
+ config: &Configuration,
+ _telemetry_handle: Option,
+ task_manager: &TaskManager,
+ ) -> sc_service::error::Result> {
+ Ok(sc_consensus_manual_seal::import_queue(
+ Box::new(client.clone()),
+ &task_manager.spawn_essential_handle(),
+ config.prometheus_registry(),
+ ))
+ }
+}
+
+impl BaseNodeSpec for ManualSealNode {
+ type Block = NodeSpec::Block;
+ type RuntimeApi = NodeSpec::RuntimeApi;
+ type BuildImportQueue = Self;
+ type InitBlockImport = ClientBlockImport;
+}
+
+impl ManualSealNode {
+ pub fn new() -> Self {
+ Self(Default::default())
+ }
+
+ pub fn start_node(
+ &self,
+ mut config: Configuration,
+ para_id: ParaId,
+ block_time: u64,
+ ) -> sc_service::error::Result
+ where
+ Net: NetworkBackend,
+ {
+ let PartialComponents {
+ client,
+ backend,
+ mut task_manager,
+ import_queue,
+ keystore_container,
+ select_chain: _,
+ transaction_pool,
+ other: (_, mut telemetry, _, _),
+ } = Self::new_partial(&config)?;
+ let select_chain = LongestChain::new(backend.clone());
+
+ // Since this is a dev node, prevent it from connecting to peers.
+ config.network.default_peers_set.in_peers = 0;
+ config.network.default_peers_set.out_peers = 0;
+ let net_config = sc_network::config::FullNetworkConfiguration::<_, _, Net>::new(
+ &config.network,
+ config.prometheus_config.as_ref().map(|cfg| cfg.registry.clone()),
+ );
+ let metrics = Net::register_notification_metrics(
+ config.prometheus_config.as_ref().map(|cfg| &cfg.registry),
+ );
+
+ let (network, system_rpc_tx, tx_handler_controller, sync_service) =
+ sc_service::build_network(sc_service::BuildNetworkParams {
+ config: &config,
+ client: client.clone(),
+ transaction_pool: transaction_pool.clone(),
+ spawn_handle: task_manager.spawn_handle(),
+ import_queue,
+ net_config,
+ block_announce_validator_builder: None,
+ warp_sync_config: None,
+ block_relay: None,
+ metrics,
+ })?;
+
+ if config.offchain_worker.enabled {
+ let offchain_workers =
+ sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions {
+ runtime_api_provider: client.clone(),
+ keystore: Some(keystore_container.keystore()),
+ offchain_db: backend.offchain_storage(),
+ transaction_pool: Some(OffchainTransactionPoolFactory::new(
+ transaction_pool.clone(),
+ )),
+ network_provider: Arc::new(network.clone()),
+ is_validator: config.role.is_authority(),
+ enable_http_requests: true,
+ custom_extensions: move |_| vec![],
+ })?;
+ task_manager.spawn_handle().spawn(
+ "offchain-workers-runner",
+ "offchain-work",
+ offchain_workers.run(client.clone(), task_manager.spawn_handle()).boxed(),
+ );
+ }
+
+ let proposer = sc_basic_authorship::ProposerFactory::new(
+ task_manager.spawn_handle(),
+ client.clone(),
+ transaction_pool.clone(),
+ None,
+ None,
+ );
+
+ let (manual_seal_sink, manual_seal_stream) = futures::channel::mpsc::channel(1024);
+ let mut manual_seal_sink_clone = manual_seal_sink.clone();
+ task_manager
+ .spawn_essential_handle()
+ .spawn("block_authoring", None, async move {
+ loop {
+ futures_timer::Delay::new(std::time::Duration::from_millis(block_time)).await;
+ manual_seal_sink_clone
+ .try_send(sc_consensus_manual_seal::EngineCommand::SealNewBlock {
+ create_empty: true,
+ finalize: true,
+ parent_hash: None,
+ sender: None,
+ })
+ .unwrap();
+ }
+ });
+
+ let client_for_cidp = client.clone();
+ let params = sc_consensus_manual_seal::ManualSealParams {
+ block_import: client.clone(),
+ env: proposer,
+ client: client.clone(),
+ pool: transaction_pool.clone(),
+ select_chain,
+ commands_stream: Box::pin(manual_seal_stream),
+ consensus_data_provider: None,
+ create_inherent_data_providers: move |block: Hash, ()| {
+ let current_para_head = client_for_cidp
+ .header(block)
+ .expect("Header lookup should succeed")
+ .expect("Header passed in as parent should be present in backend.");
+
+ let should_send_go_ahead = client_for_cidp
+ .runtime_api()
+ .collect_collation_info(block, ¤t_para_head)
+ .map(|info| info.new_validation_code.is_some())
+ .unwrap_or_default();
+
+ // The API version is relevant here because the constraints in the runtime changed
+ // in https://github.com/paritytech/polkadot-sdk/pull/6825. In general, the logic
+ // here assumes that we are using the aura-ext consensushook in the parachain
+ // runtime.
+ let requires_relay_progress = client_for_cidp
+ .runtime_api()
+ .has_api_with::, _>(
+ block,
+ |version| version > 1,
+ )
+ .ok()
+ .unwrap_or_default();
+
+ let current_para_block_head =
+ Some(polkadot_primitives::HeadData(current_para_head.encode()));
+ let client_for_xcm = client_for_cidp.clone();
+ async move {
+ use sp_runtime::traits::UniqueSaturatedInto;
+
+ let mocked_parachain = MockValidationDataInherentDataProvider {
+ // When using manual seal we start from block 0, and it's very unlikely to
+ // reach a block number > u32::MAX.
+ current_para_block: UniqueSaturatedInto::::unique_saturated_into(
+ *current_para_head.number(),
+ ),
+ para_id,
+ current_para_block_head,
+ relay_offset: 0,
+ relay_blocks_per_para_block: requires_relay_progress
+ .then(|| 1)
+ .unwrap_or_default(),
+ para_blocks_per_relay_epoch: 10,
+ relay_randomness_config: (),
+ xcm_config: MockXcmConfig::new(&*client_for_xcm, block, Default::default()),
+ raw_downward_messages: vec![],
+ raw_horizontal_messages: vec![],
+ additional_key_values: None,
+ upgrade_go_ahead: should_send_go_ahead.then(|| {
+ log::info!(
+ "Detected pending validation code, sending go-ahead signal."
+ );
+ UpgradeGoAhead::GoAhead
+ }),
+ };
+ Ok((
+ // This is intentional, as the runtime that we expect to run against this
+ // will never receive the aura-related inherents/digests, and providing
+ // real timestamps would cause aura <> timestamp checking to fail.
+ sp_timestamp::InherentDataProvider::new(sp_timestamp::Timestamp::new(0)),
+ mocked_parachain,
+ ))
+ }
+ },
+ };
+ let authorship_future = sc_consensus_manual_seal::run_manual_seal(params);
+ task_manager.spawn_essential_handle().spawn_blocking(
+ "manual-seal",
+ None,
+ authorship_future,
+ );
+ let rpc_extensions_builder = {
+ let client = client.clone();
+ let transaction_pool = transaction_pool.clone();
+ let backend_for_rpc = backend.clone();
+
+ Box::new(move |_| {
+ let mut module = NodeSpec::BuildRpcExtensions::build_rpc_extensions(
+ client.clone(),
+ backend_for_rpc.clone(),
+ transaction_pool.clone(),
+ )?;
+ module
+ .merge(ManualSeal::new(manual_seal_sink.clone()).into_rpc())
+ .map_err(|e| sc_service::Error::Application(e.into()))?;
+ Ok(module)
+ })
+ };
+
+ let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
+ network,
+ client: client.clone(),
+ keystore: keystore_container.keystore(),
+ task_manager: &mut task_manager,
+ transaction_pool: transaction_pool.clone(),
+ rpc_builder: rpc_extensions_builder,
+ backend,
+ system_rpc_tx,
+ tx_handler_controller,
+ sync_service,
+ config,
+ telemetry: telemetry.as_mut(),
+ })?;
+
+ Ok(task_manager)
+ }
+}
diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs
index 907f09263fc1..a60391aaa1e0 100644
--- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs
+++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs
@@ -28,6 +28,11 @@ pub mod types;
use cumulus_primitives_core::CollectCollationInfo;
use sc_client_db::DbHash;
+<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs
+=======
+use sc_offchain::OffchainWorkerApi;
+use serde::de::DeserializeOwned;
+>>>>>>> 87f4f3f0 (omni-node: add offchain worker (#7479)):cumulus/polkadot-omni-node/lib/src/common/mod.rs
use sp_api::{ApiExt, CallApiAt, ConstructRuntimeApi, Metadata};
use sp_block_builder::BlockBuilder;
use sp_runtime::{
@@ -65,6 +70,7 @@ pub trait NodeRuntimeApi:
+ SessionKeys
+ BlockBuilder
+ TaggedTransactionQueue
+ + OffchainWorkerApi
+ CollectCollationInfo
+ Sized
{
@@ -76,6 +82,11 @@ impl NodeRuntimeApi for T where
+ SessionKeys
+ BlockBuilder
+ TaggedTransactionQueue
+<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs
+=======
+ + OffchainWorkerApi
+ + GetCoreSelectorApi
+>>>>>>> 87f4f3f0 (omni-node: add offchain worker (#7479)):cumulus/polkadot-omni-node/lib/src/common/mod.rs
+ CollectCollationInfo
{
}
diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
index 0c0230296eb8..cd85e17552ff 100644
--- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
+++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
@@ -30,16 +30,24 @@ use cumulus_client_service::{
};
use cumulus_primitives_core::{BlockT, ParaId};
use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface};
+use futures::FutureExt;
use parachains_common::Hash;
use polkadot_primitives::CollatorPair;
use prometheus_endpoint::Registry;
+use sc_client_api::Backend;
use sc_consensus::DefaultImportQueue;
use sc_executor::{HeapAllocStrategy, DEFAULT_HEAP_ALLOC_STRATEGY};
use sc_network::{config::FullNetworkConfiguration, NetworkBackend, NetworkBlock};
use sc_service::{Configuration, ImportQueue, PartialComponents, TaskManager};
use sc_sysinfo::HwBench;
use sc_telemetry::{TelemetryHandle, TelemetryWorker};
+<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
use sc_transaction_pool::FullPool;
+=======
+use sc_tracing::tracing::Instrument;
+use sc_transaction_pool::TransactionPoolHandle;
+use sc_transaction_pool_api::OffchainTransactionPoolFactory;
+>>>>>>> 87f4f3f0 (omni-node: add offchain worker (#7479)):cumulus/polkadot-omni-node/lib/src/common/spec.rs
use sp_keystore::KeystorePtr;
use std::{future::Future, pin::Pin, sync::Arc, time::Duration};
@@ -246,6 +254,27 @@ pub(crate) trait NodeSpec {
})
.await?;
+ if parachain_config.offchain_worker.enabled {
+ let offchain_workers =
+ sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions {
+ runtime_api_provider: client.clone(),
+ keystore: Some(params.keystore_container.keystore()),
+ offchain_db: backend.offchain_storage(),
+ transaction_pool: Some(OffchainTransactionPoolFactory::new(
+ transaction_pool.clone(),
+ )),
+ network_provider: Arc::new(network.clone()),
+ is_validator: parachain_config.role.is_authority(),
+ enable_http_requests: false,
+ custom_extensions: move |_| vec![],
+ })?;
+ task_manager.spawn_handle().spawn(
+ "offchain-workers-runner",
+ "offchain-work",
+ offchain_workers.run(client.clone(), task_manager.spawn_handle()).boxed(),
+ );
+ }
+
let rpc_builder = {
let client = client.clone();
let transaction_pool = transaction_pool.clone();
diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/fake_runtime_api/utils.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/fake_runtime_api/utils.rs
index 442b87b5d775..245709cf81b5 100644
--- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/fake_runtime_api/utils.rs
+++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/fake_runtime_api/utils.rs
@@ -110,6 +110,12 @@ macro_rules! impl_node_runtime_apis {
}
}
+ impl sp_offchain::OffchainWorkerApi<$block> for $runtime {
+ fn offchain_worker(_: &<$block as BlockT>::Header) {
+ unimplemented!()
+ }
+ }
+
impl sp_session::SessionKeys<$block> for $runtime {
fn generate_session_keys(_: Option>) -> Vec {
unimplemented!()
diff --git a/prdoc/pr_7479.prdoc b/prdoc/pr_7479.prdoc
new file mode 100644
index 000000000000..444eaa420a45
--- /dev/null
+++ b/prdoc/pr_7479.prdoc
@@ -0,0 +1,9 @@
+title: 'omni-node: add offchain worker'
+doc:
+- audience: [ Runtime Dev, Node Dev, Node Operator ]
+ description: |-
+ Added support for offchain worker to omni-node-lib for both aura and manual seal nodes.
+
+crates:
+- name: polkadot-omni-node-lib
+ bump: patch