diff --git a/Cargo.lock b/Cargo.lock index c09ed45733408cb576e37fb98b54596ab3a90512..57c70150a20725e002140ed290b3b1987d01cf76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18126,6 +18126,7 @@ dependencies = [ "sc-consensus-manual-seal", "sc-executor 0.32.0", "sc-network", + "sc-offchain", "sc-rpc", "sc-runtime-utilities", "sc-service", @@ -18133,6 +18134,7 @@ dependencies = [ "sc-telemetry", "sc-tracing", "sc-transaction-pool", + "sc-transaction-pool-api", "scale-info", "serde", "serde_json", @@ -18145,6 +18147,7 @@ dependencies = [ "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", diff --git a/cumulus/polkadot-omni-node/lib/Cargo.toml b/cumulus/polkadot-omni-node/lib/Cargo.toml index 018fc88a2aeaf2018681e96a7e4baccaa17b2afa..020d980d3d9d6f96ed05f6afa474f695873d40d9 100644 --- a/cumulus/polkadot-omni-node/lib/Cargo.toml +++ b/cumulus/polkadot-omni-node/lib/Cargo.toml @@ -50,6 +50,7 @@ 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 } @@ -57,6 +58,7 @@ 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 } @@ -66,6 +68,7 @@ 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 } diff --git a/cumulus/polkadot-omni-node/lib/src/common/mod.rs b/cumulus/polkadot-omni-node/lib/src/common/mod.rs index 37660a5347a20b8fad5b6452eed331f98806c8d7..843183425dabfa44f481855691dfaba69cd056fa 100644 --- a/cumulus/polkadot-omni-node/lib/src/common/mod.rs +++ b/cumulus/polkadot-omni-node/lib/src/common/mod.rs @@ -28,6 +28,7 @@ pub mod types; use cumulus_primitives_core::{CollectCollationInfo, GetCoreSelectorApi}; use sc_client_db::DbHash; +use sc_offchain::OffchainWorkerApi; use serde::de::DeserializeOwned; use sp_api::{ApiExt, CallApiAt, ConstructRuntimeApi, Metadata}; use sp_block_builder::BlockBuilder; @@ -65,6 +66,7 @@ pub trait NodeRuntimeApi<Block: BlockT>: + SessionKeys<Block> + BlockBuilder<Block> + TaggedTransactionQueue<Block> + + OffchainWorkerApi<Block> + CollectCollationInfo<Block> + GetCoreSelectorApi<Block> + Sized @@ -77,6 +79,7 @@ impl<T, Block: BlockT> NodeRuntimeApi<Block> for T where + SessionKeys<Block> + BlockBuilder<Block> + TaggedTransactionQueue<Block> + + OffchainWorkerApi<Block> + GetCoreSelectorApi<Block> + CollectCollationInfo<Block> { diff --git a/cumulus/polkadot-omni-node/lib/src/common/spec.rs b/cumulus/polkadot-omni-node/lib/src/common/spec.rs index 868368f3ca1a7b2179854ad77cbba52bf97ae5a0..d497337904b9798fcaaa2aa5d78853d33b959fb8 100644 --- a/cumulus/polkadot-omni-node/lib/src/common/spec.rs +++ b/cumulus/polkadot-omni-node/lib/src/common/spec.rs @@ -30,9 +30,11 @@ 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}; @@ -41,6 +43,7 @@ use sc_sysinfo::HwBench; use sc_telemetry::{TelemetryHandle, TelemetryWorker}; use sc_tracing::tracing::Instrument; use sc_transaction_pool::TransactionPoolHandle; +use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_keystore::KeystorePtr; use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; @@ -303,6 +306,27 @@ pub(crate) trait NodeSpec: BaseNodeSpec { }) .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-omni-node/lib/src/fake_runtime_api/utils.rs b/cumulus/polkadot-omni-node/lib/src/fake_runtime_api/utils.rs index 6bfd5f4f4cbd1743782303d0d5f6ab78d16c7b4a..915f156f8cb53ceee4b4d5976297586f11438f96 100644 --- a/cumulus/polkadot-omni-node/lib/src/fake_runtime_api/utils.rs +++ b/cumulus/polkadot-omni-node/lib/src/fake_runtime_api/utils.rs @@ -111,6 +111,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<u8>>) -> Vec<u8> { unimplemented!() diff --git a/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs b/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs index 92a55b2adbea16fa232013c31bee3dcd80542d24..96802177ec1049e5b508015cca634636b894355a 100644 --- a/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs +++ b/cumulus/polkadot-omni-node/lib/src/nodes/manual_seal.rs @@ -23,12 +23,15 @@ 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}; @@ -118,6 +121,27 @@ impl<NodeSpec: NodeSpecT> ManualSealNode<NodeSpec> { 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(), diff --git a/prdoc/pr_7479.prdoc b/prdoc/pr_7479.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..444eaa420a4562ebe2ad0bb298b197fd83e5f036 --- /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