3

After upgrading to 0.9.42, we have ERROR tokio-runtime-worker sc_service::task_manager: Essential task babe-worker failed. Shutting down service. error starting the node using cargo run -- --dev. Using cargo run -- --dev --sealing=instant the node starts correctly.

The update requires a few modifications concerning babe in node/src/:

diff --git a/node/src/command/key.rs b/node/src/command/key.rs
index 655ebc2..6aa6ffe 100644
--- a/node/src/command/key.rs
+++ b/node/src/command/key.rs
@@ -20,7 +20,7 @@ use sc_cli::{
 use sc_keystore::LocalKeystore;
 use sc_service::config::{BasePath, KeystoreConfig};
 use sp_core::crypto::{AccountId32, KeyTypeId, SecretString};
-use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
+use sp_keystore::{Keystore, KeystorePtr};
 use std::sync::Arc;
 
 #[derive(Debug, clap::Subcommand)]
@@ -82,18 +82,17 @@ impl GenSessionKeysCmd {
         let mut public_keys_bytes = Vec::with_capacity(128);
         for (key_type_id, crypto_scheme) in KEY_TYPES {
             let (keystore, public) = match self.keystore_params.keystore_config(&config_dir)? {
-                (_, KeystoreConfig::Path { path, password }) => {
+                KeystoreConfig::Path { path, password } => {
                     let public =
                         with_crypto_scheme!(crypto_scheme, to_vec(&suri, password.clone()))?;
-                    let keystore: SyncCryptoStorePtr =
-                        Arc::new(LocalKeystore::open(path, password)?);
+                    let keystore: KeystorePtr = Arc::new(LocalKeystore::open(path, password)?);
                     (keystore, public)
                 }
                 _ => unreachable!("keystore_config always returns path and password; qed"),
             };
 
-            SyncCryptoStore::insert_unknown(&*keystore, key_type_id, &suri, &public[..])
-                .map_err(|_| Error::KeyStoreOperation)?;
+            Keystore::insert(&*keystore, key_type_id, &suri, &public[..])
+                .map_err(|_| Error::KeystoreOperation)?;
 
             public_keys_bytes.extend_from_slice(&public[..]);
         }
diff --git a/node/src/service.rs b/node/src/service.rs
index 258b8af..8cb3132 100644
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -238,13 +238,6 @@ where
         RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
     Executor: sc_executor::NativeExecutionDispatch + 'static,
 {
-    if config.keystore_remote.is_some() {
-        return Err(ServiceError::Other(
-            "Remote Keystores are not supported.".to_owned(),
-        ));
-    }
-    // TODO deprecated ?
-
     let telemetry = config
         .telemetry_endpoints
         .clone()
@@ -311,7 +304,7 @@ where
         )
     } else {
         let slot_duration = babe_link.config().slot_duration();
-        let import_queue = sc_consensus_babe::import_queue(
+        let (import_queue, _) = sc_consensus_babe::import_queue(
             babe_link.clone(),
             babe_block_import.clone(),
             Some(Box::new(justification_import)),
@@ -347,13 +340,6 @@ where
     })
 }
 
-fn remote_keystore(_url: &str) -> Result<Arc<LocalKeystore>, &'static str> {
-    // FIXME: here would the concrete keystore be built,
-    //        must return a concrete type (NOT `LocalKeystore`) that
-    //        implements `CryptoStore` and `SyncCryptoStore`
-    Err("Remote Keystore not supported.")
-}
-
 /// Builds a new service for a full client.
 pub fn new_full<RuntimeApi, Executor>(
     mut config: Configuration,
@@ -373,24 +359,12 @@ where
         backend,
         mut task_manager,
         import_queue,
-        mut keystore_container,
+        keystore_container,
         select_chain,
         transaction_pool,
         other: (block_import, babe_link, grandpa_link, mut telemetry),
     } = new_partial::<RuntimeApi, Executor>(&config, sealing.is_manual_consensus())?;
 
-    if let Some(url) = &config.keystore_remote {
-        match remote_keystore(url) {
-            Ok(k) => keystore_container.set_remote_keystore(k),
-            Err(e) => {
-                return Err(ServiceError::Other(format!(
-                    "Error hooking up remote keystore for {}: {}",
-                    url, e
-                )))
-            }
-        };
-    } // TODO deprecated ?
-
     let grandpa_protocol_name = sc_consensus_grandpa::protocol_standard_name(
         &client
             .block_hash(0)
@@ -415,7 +389,6 @@ where
     let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
         sc_service::build_network(sc_service::BuildNetworkParams {
             config: &config,
-            //net_config: net_config,
             client: client.clone(),
             transaction_pool: transaction_pool.clone(),
             spawn_handle: task_manager.spawn_handle(),
@@ -489,7 +462,7 @@ where
             let babe_consensus_data_provider =
                 sc_consensus_manual_seal::consensus::babe::BabeConsensusDataProvider::new(
                     client.clone(),
-                    keystore_container.sync_keystore(),
+                    keystore_container.keystore(),
                     babe_link.epoch_changes().clone(),
                     vec![(
                         sp_consensus_babe::AuthorityId::from(
@@ -532,7 +505,7 @@ where
             let client_clone = client.clone();
             let slot_duration = babe_link.config().slot_duration();
             let babe_config = sc_consensus_babe::BabeParams {
-                keystore: keystore_container.sync_keystore(),
+                keystore: keystore_container.keystore(),
                 client: client.clone(),
                 select_chain,
                 block_import,
@@ -581,7 +554,7 @@ where
 
     let rpc_extensions_builder = {
         let client = client.clone();
-        //let keystore = keystore_container.sync_keystore();
+        //let keystore = keystore_container.keystore();
         let pool = transaction_pool.clone();
         //let select_chain = select_chain.clone();
         //let chain_spec = config.chain_spec.cloned_box();
@@ -611,7 +584,7 @@ where
         network: network.clone(),
         sync_service: sync_service.clone(),
         client,
-        keystore: keystore_container.sync_keystore(),
+        keystore: keystore_container.keystore(),
         task_manager: &mut task_manager,
         transaction_pool,
         rpc_builder: rpc_extensions_builder,
@@ -623,7 +596,7 @@ where
     // if the node isn't actively participating in consensus then it doesn't
     // need a keystore, regardless of which protocol we use below.
     let keystore = if role.is_authority() {
-        Some(keystore_container.sync_keystore())
+        Some(keystore_container.keystore())
     } else {
         None
     };

Any ideas where this error might come from?

1 Answer 1

1

Finally, I tracked the error to https://github.com/paritytech/substrate/commit/cb954820a8d8d765ce75021e244223a3b4d5722d and the solution is to add BabeDeps dependency that uses babe_worker_handle to instantiate the RPC extensions (that seem to be mandatory for 0.9.42).

diff --git a/node/src/rpc.rs b/node/src/rpc.rs
index 039e43e..cb13628 100644
--- a/node/src/rpc.rs
+++ b/node/src/rpc.rs
@@ -26,29 +26,47 @@ pub use sc_rpc_api::DenyUnsafe;
 use common_runtime::Block;
 use common_runtime::{AccountId, Balance, Index};
 use jsonrpsee::RpcModule;
+use sc_consensus_babe::BabeApi;
+use sc_consensus_babe::BabeWorkerHandle;
 use sc_transaction_pool_api::TransactionPool;
 use sp_api::ProvideRuntimeApi;
 use sp_block_builder::BlockBuilder;
 use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
+use sp_consensus::SelectChain;
+use sp_keystore::KeystorePtr;
 use std::sync::Arc;
 
+/// Extra dependencies for BABE.
+pub struct BabeDeps {
+    /// A handle to the BABE worker for issuing requests.
+    pub babe_worker_handle: BabeWorkerHandle<Block>,
+    /// The keystore that manages the keys of the node.
+    pub keystore: KeystorePtr,
+}
+
 /// Full client dependencies.
-pub struct FullDeps<C, P> {
+pub struct FullDeps<C, P, SC> {
     /// The client instance to use.
     pub client: Arc<C>,
     /// Transaction pool instance.
     pub pool: Arc<P>,
+    /// The SelectChain Strategy
+    pub select_chain: SC,
+    /// A copy of the chain spec.
+    pub chain_spec: Box<dyn sc_chain_spec::ChainSpec>,
     /// Whether to deny unsafe calls
     pub deny_unsafe: DenyUnsafe,
     /// Manual seal command sink
     pub command_sink_opt: Option<
         futures::channel::mpsc::Sender<sc_consensus_manual_seal::EngineCommand<sp_core::H256>>,
     >,
+    /// BABE specific dependencies.
+    pub babe: BabeDeps,
 }
 
 /// Instantiate all full RPC extensions.
-pub fn create_full<C, P>(
-    deps: FullDeps<C, P>,
+pub fn create_full<C, P, SC>(
+    deps: FullDeps<C, P, SC>,
 ) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
 where
     C: ProvideRuntimeApi<Block>,
@@ -56,10 +74,13 @@ where
     C: Send + Sync + 'static,
     C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
     C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
+    C::Api: BabeApi<Block>,
     C::Api: BlockBuilder<Block>,
     P: TransactionPool + 'static,
+    SC: SelectChain<Block> + 'static,
 {
     use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
+    use sc_consensus_babe_rpc::{Babe, BabeApiServer};
     use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer};
     use substrate_frame_rpc_system::{System, SystemApiServer};
 
@@ -67,13 +88,30 @@ where
     let FullDeps {
         client,
         pool,
+        select_chain,
+        chain_spec,
         deny_unsafe,
         command_sink_opt,
+        babe,
     } = deps;
 
-    module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
-    module.merge(TransactionPayment::new(client).into_rpc())?;
+    let BabeDeps {
+        babe_worker_handle,
+        keystore,
+    } = babe;
 
+    module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
+    module.merge(TransactionPayment::new(client.clone()).into_rpc())?;
+    module.merge(
+        Babe::new(
+            client.clone(),
+            babe_worker_handle.clone(),
+            keystore,
+            select_chain,
+            deny_unsafe,
+        )
+        .into_rpc(),
+    )?;
     if let Some(command_sink) = command_sink_opt {
         // We provide the rpc handler with the sending end of the channel to allow the rpc
         // send EngineCommands to the background block authorship task.
diff --git a/node/src/service.rs b/node/src/service.rs
index 55443d3..eb636f6 100644
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -218,6 +218,7 @@ pub fn new_partial<RuntimeApi, Executor>(
                 FullGrandpaBlockImport<RuntimeApi, Executor>,
             >,
             sc_consensus_babe::BabeLink<Block>,
+            sc_consensus_babe::BabeWorkerHandle<Block>,
             sc_consensus_grandpa::LinkHalf<
                 Block,
                 FullClient<RuntimeApi, Executor>,
@@ -237,13 +238,6 @@ where
         RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
     Executor: sc_executor::NativeExecutionDispatch + 'static,
 {
-    /*if config.keystore_remote.is_some() {
-        return Err(ServiceError::Other(
-            "Remote Keystores are not supported.".to_owned(),
-        ));
-    }*/
-    // TODO deprecated ?
-
     let telemetry = config
         .telemetry_endpoints
         .clone()
@@ -297,37 +291,36 @@ where
         client.clone(),
     )?;
 
-    let import_queue = if consensus_manual {
-        sc_consensus_manual_seal::import_queue(
+    let slot_duration = babe_link.config().slot_duration();
+    let (import_queue, babe_worker_handle) = sc_consensus_babe::import_queue(
+        babe_link.clone(),
+        babe_block_import.clone(),
+        Some(Box::new(justification_import)),
+        client.clone(),
+        select_chain.clone(),
+        move |_, ()| async move {
+            let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
+
+            let slot =
+                sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
+                    *timestamp,
+                    slot_duration,
+                );
+            Ok((slot, timestamp))
+        },
+        &task_manager.spawn_essential_handle(),
+        config.prometheus_registry(),
+        telemetry.as_ref().map(|x| x.handle()),
+    )?;
+
+    // Shadow import_queue
+    if consensus_manual {
+        let import_queue = sc_consensus_manual_seal::import_queue(
             Box::new(babe_block_import.clone()),
             &task_manager.spawn_essential_handle(),
             config.prometheus_registry(),
-        )
-    } else {
-        let slot_duration = babe_link.config().slot_duration();
-        let (import_queue, _) = sc_consensus_babe::import_queue(
-            babe_link.clone(),
-            babe_block_import.clone(),
-            Some(Box::new(justification_import)),
-            client.clone(),
-            select_chain.clone(),
-            move |_, ()| async move {
-                let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
-
-                let slot =
-                    sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
-                        *timestamp,
-                        slot_duration,
-                    );
-
-                Ok((slot, timestamp))
-            },
-            &task_manager.spawn_essential_handle(),
-            config.prometheus_registry(),
-            telemetry.as_ref().map(|x| x.handle()),
-        )?;
-        import_queue
-    };
+        );
+    }
 
     Ok(sc_service::PartialComponents {
         client,
@@ -337,7 +330,13 @@ where
         keystore_container,
         select_chain,
         transaction_pool,
-        other: (babe_block_import, babe_link, grandpa_link, telemetry),
+        other: (
+            babe_block_import,
+            babe_link,
+            babe_worker_handle,
+            grandpa_link,
+            telemetry,
+        ),
     })
 }
 
@@ -363,21 +362,9 @@ where
         keystore_container,
         select_chain,
         transaction_pool,
-        other: (block_import, babe_link, grandpa_link, mut telemetry),
+        other: (block_import, babe_link, babe_worker_handle, grandpa_link, mut telemetry),
     } = new_partial::<RuntimeApi, Executor>(&config, sealing.is_manual_consensus())?;
 
-    /*if let Some(url) = &config.keystore_remote {
-        match remote_keystore(url) {
-            Ok(k) => keystore_container.set_remote_keystore(k),
-            Err(e) => {
-                return Err(ServiceError::Other(format!(
-                    "Error hooking up remote keystore for {}: {}",
-                    url, e
-                )))
-            }
-        };
-    }*/// TODO deprecated ?
-
     let grandpa_protocol_name = sc_consensus_grandpa::protocol_standard_name(
         &client
             .block_hash(0)
@@ -398,11 +385,9 @@ where
         Vec::default(),
     ));
 
-    //let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);
     let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
         sc_service::build_network(sc_service::BuildNetworkParams {
             config: &config,
-            //net_config: net_config,
             client: client.clone(),
             transaction_pool: transaction_pool.clone(),
             spawn_handle: task_manager.spawn_handle(),
@@ -497,7 +482,7 @@ where
                     client: client.clone(),
                     pool: transaction_pool.clone(),
                     commands_stream,
-                    select_chain,
+                    select_chain: select_chain.clone(),
                     consensus_data_provider: Some(Box::new(babe_consensus_data_provider)),
                     create_inherent_data_providers: move |_, _| {
                         let client = client_clone.clone();
@@ -521,7 +506,7 @@ where
             let babe_config = sc_consensus_babe::BabeParams {
                 keystore: keystore_container.keystore(),
                 client: client.clone(),
-                select_chain,
+                select_chain: select_chain.clone(),
                 block_import,
                 env: proposer_factory,
                 sync_oracle: sync_service.clone(),
@@ -568,23 +553,22 @@ where
 
     let rpc_extensions_builder = {
         let client = client.clone();
-        //let keystore = keystore_container.sync_keystore();
         let pool = transaction_pool.clone();
-        //let select_chain = select_chain.clone();
-        //let chain_spec = config.chain_spec.cloned_box();
+        let select_chain = select_chain.clone();
+        let chain_spec = config.chain_spec.cloned_box();
+        let keystore = keystore_container.keystore().clone();
 
         Box::new(move |deny_unsafe, _| {
             let deps = crate::rpc::FullDeps {
                 client: client.clone(),
                 pool: pool.clone(),
-                //select_chain: select_chain.clone(),
-                //chain_spec: chain_spec.cloned_box(),
+                select_chain: select_chain.clone(),
+                chain_spec: chain_spec.cloned_box(),
                 deny_unsafe,
-                /*babe: crate::rpc::BabeDeps {
-                    babe_config: babe_config.clone(),
-                    shared_epoch_changes: shared_epoch_changes.clone(),
+                babe: crate::rpc::BabeDeps {
+                    babe_worker_handle: babe_worker_handle.clone(),
                     keystore: keystore.clone(),
-                },*/
+                },
                 command_sink_opt: command_sink_opt.clone(),
             };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.