mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 06:21:11 +00:00
Refactor key management (#3296)
* Add Call type to extensible transactions. Cleanup some naming * Merge Resource and BlockExhausted into just Exhausted * Fix * Another fix * Call * Some fixes * Fix srml tests. * Fix all tests. * Refactor crypto so each application of it has its own type. * Introduce new AuthorityProvider API into Aura This will eventually allow for dynamic determination of authority keys and avoid having to set them directly on CLI. * Introduce authority determinator for Babe. Experiment with modular consensus API. * Work in progress to introduce KeyTypeId and avoid polluting API with validator IDs * Finish up drafting imonline * Rework offchain workers API. * Rework API implementation. * Make it compile for wasm, simplify app_crypto. * Fix compilation of im-online. * Fix compilation of im-online. * Fix more compilation errors. * Make it compile. * Fixing tests. * Rewrite `keystore` * Fix session tests * Bring back `TryFrom`'s' * Fix `srml-grandpa` * Fix `srml-aura` * Fix consensus babe * More fixes * Make service generate keys from dev_seed * Build fixes * Remove offchain tests * More fixes and cleanups * Fixes finality grandpa * Fix `consensus-aura` * Fix cli * Fix `node-cli` * Fix chain_spec builder * Fix doc tests * Add authority getter for grandpa. * Test fix * Fixes * Make keystore accessible from the runtime * Move app crypto to its own crate * Update `Cargo.lock` * Make the crypto stuff usable from the runtime * Adds some runtime crypto tests * Use last finalized block for grandpa authority * Fix warning * Adds `SessionKeys` runtime api * Remove `FinalityPair` and `ConsensusPair` * Minor governance tweaks to get it inline with docs. * Make the governance be up to date with the docs. * Build fixes. * Generate the inital session keys * Failing keystore is a hard error * Make babe work again * Fix grandpa * Fix tests * Disable `keystore` in consensus critical stuff * Build fix. * ImOnline supports multiple authorities at once. * Update core/application-crypto/src/ed25519.rs * Merge branch 'master' into gav-in-progress * Remove unneeded code for now. * Some `session` testing * Support querying the public keys * Cleanup offchain * Remove warnings * More cleanup * Apply suggestions from code review Co-Authored-By: Benjamin Kampmann <ben.kampmann@googlemail.com> * More cleanups * JSONRPC API for setting keys. Also, rename traits::KeyStore* -> traits::BareCryptoStore* * Bad merge * Fix integration tests * Fix test build * Test fix * Fixes * Warnings * Another warning * Bump version.
This commit is contained in:
@@ -34,7 +34,7 @@ enum GenesisSource<G> {
|
||||
Factory(fn() -> G),
|
||||
}
|
||||
|
||||
impl<G: RuntimeGenesis> Clone for GenesisSource<G> {
|
||||
impl<G> Clone for GenesisSource<G> {
|
||||
fn clone(&self) -> Self {
|
||||
match *self {
|
||||
GenesisSource::File(ref path) => GenesisSource::File(path.clone()),
|
||||
@@ -104,12 +104,12 @@ struct ChainSpecFile {
|
||||
pub type Properties = json::map::Map<String, json::Value>;
|
||||
|
||||
/// A configuration of a chain. Can be used to build a genesis block.
|
||||
pub struct ChainSpec<G: RuntimeGenesis> {
|
||||
pub struct ChainSpec<G> {
|
||||
spec: ChainSpecFile,
|
||||
genesis: GenesisSource<G>,
|
||||
}
|
||||
|
||||
impl<G: RuntimeGenesis> Clone for ChainSpec<G> {
|
||||
impl<G> Clone for ChainSpec<G> {
|
||||
fn clone(&self) -> Self {
|
||||
ChainSpec {
|
||||
spec: self.spec.clone(),
|
||||
|
||||
@@ -19,18 +19,21 @@
|
||||
use std::{sync::Arc, ops::Deref, ops::DerefMut};
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use crate::chain_spec::ChainSpec;
|
||||
use keystore::KeyStorePtr;
|
||||
use client_db;
|
||||
use client::{self, Client, runtime_api};
|
||||
use crate::{error, Service, AuthorityKeyProvider};
|
||||
use crate::{error, Service};
|
||||
use consensus_common::{import_queue::ImportQueue, SelectChain};
|
||||
use network::{self, OnDemand, FinalityProofProvider, NetworkStateInfo, config::BoxFinalityProofRequestBuilder};
|
||||
use network::{
|
||||
self, OnDemand, FinalityProofProvider, NetworkStateInfo, config::BoxFinalityProofRequestBuilder
|
||||
};
|
||||
use substrate_executor::{NativeExecutor, NativeExecutionDispatch};
|
||||
use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool};
|
||||
use sr_primitives::{
|
||||
BuildStorage, traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}, generic::BlockId
|
||||
};
|
||||
use crate::config::Configuration;
|
||||
use primitives::{Blake2Hasher, H256, Pair};
|
||||
use primitives::{Blake2Hasher, H256, traits::BareCryptoStorePtr};
|
||||
use rpc::{self, apis::system::SystemInfo};
|
||||
use futures::{prelude::*, future::Executor};
|
||||
use futures03::channel::mpsc;
|
||||
@@ -129,16 +132,6 @@ pub type ComponentOffchainStorage<C> = <
|
||||
/// Block type for `Components`
|
||||
pub type ComponentBlock<C> = <<C as Components>::Factory as ServiceFactory>::Block;
|
||||
|
||||
/// ConsensusPair type for `Components`
|
||||
pub type ComponentConsensusPair<C> = <<C as Components>::Factory as ServiceFactory>::ConsensusPair;
|
||||
|
||||
/// FinalityPair type for `Components`
|
||||
pub type ComponentFinalityPair<C> = <<C as Components>::Factory as ServiceFactory>::FinalityPair;
|
||||
|
||||
/// AuthorityKeyProvider type for `Components`
|
||||
pub type ComponentAuthorityKeyProvider<C> =
|
||||
AuthorityKeyProvider<ComponentBlock<C>, ComponentConsensusPair<C>, ComponentFinalityPair<C>>;
|
||||
|
||||
/// Extrinsic hash type for `Components`
|
||||
pub type ComponentExHash<C> = <<C as Components>::TransactionPoolApi as txpool::ChainApi>::Hash;
|
||||
|
||||
@@ -152,6 +145,27 @@ pub type PoolApi<C> = <C as Components>::TransactionPoolApi;
|
||||
pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {}
|
||||
impl<T: Serialize + DeserializeOwned + BuildStorage> RuntimeGenesis for T {}
|
||||
|
||||
/// Something that can create initial session keys from given seeds.
|
||||
pub trait InitialSessionKeys<C: Components> {
|
||||
/// Generate the initial session keys for the given seeds.
|
||||
fn generate_intial_session_keys(
|
||||
client: Arc<ComponentClient<C>>,
|
||||
seeds: Vec<String>,
|
||||
) -> error::Result<()>;
|
||||
}
|
||||
|
||||
impl<C: Components> InitialSessionKeys<Self> for C where
|
||||
ComponentClient<C>: ProvideRuntimeApi,
|
||||
<ComponentClient<C> as ProvideRuntimeApi>::Api: substrate_session::SessionKeys<ComponentBlock<C>>,
|
||||
{
|
||||
fn generate_intial_session_keys(
|
||||
client: Arc<ComponentClient<C>>,
|
||||
seeds: Vec<String>,
|
||||
) -> error::Result<()> {
|
||||
substrate_session::generate_initial_session_keys(client, seeds).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that can start the RPC service.
|
||||
pub trait StartRPC<C: Components> {
|
||||
fn start_rpc(
|
||||
@@ -160,6 +174,7 @@ pub trait StartRPC<C: Components> {
|
||||
system_info: SystemInfo,
|
||||
task_executor: TaskExecutor,
|
||||
transaction_pool: Arc<TransactionPool<C::TransactionPoolApi>>,
|
||||
keystore: KeyStorePtr,
|
||||
) -> rpc::RpcHandler;
|
||||
}
|
||||
|
||||
@@ -173,11 +188,12 @@ impl<C: Components> StartRPC<Self> for C where
|
||||
rpc_system_info: SystemInfo,
|
||||
task_executor: TaskExecutor,
|
||||
transaction_pool: Arc<TransactionPool<C::TransactionPoolApi>>,
|
||||
keystore: KeyStorePtr,
|
||||
) -> rpc::RpcHandler {
|
||||
let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone());
|
||||
let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone());
|
||||
let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone());
|
||||
let author = rpc::apis::author::Author::new(client, transaction_pool, subscriptions);
|
||||
let author = rpc::apis::author::Author::new(client, transaction_pool, subscriptions, keystore);
|
||||
let system = rpc::apis::system::System::new(rpc_system_info, system_send_back);
|
||||
rpc::rpc_handler::<ComponentBlock<C>, ComponentExHash<C>, _, _, _, _>(
|
||||
state,
|
||||
@@ -242,7 +258,6 @@ pub trait OffchainWorker<C: Components> {
|
||||
offchain: &offchain::OffchainWorkers<
|
||||
ComponentClient<C>,
|
||||
ComponentOffchainStorage<C>,
|
||||
ComponentAuthorityKeyProvider<C>,
|
||||
ComponentBlock<C>
|
||||
>,
|
||||
pool: &Arc<TransactionPool<C::TransactionPoolApi>>,
|
||||
@@ -259,7 +274,6 @@ impl<C: Components> OffchainWorker<Self> for C where
|
||||
offchain: &offchain::OffchainWorkers<
|
||||
ComponentClient<C>,
|
||||
ComponentOffchainStorage<C>,
|
||||
ComponentAuthorityKeyProvider<C>,
|
||||
ComponentBlock<C>
|
||||
>,
|
||||
pool: &Arc<TransactionPool<C::TransactionPoolApi>>,
|
||||
@@ -277,6 +291,7 @@ pub trait ServiceTrait<C: Components>:
|
||||
+ StartRPC<C>
|
||||
+ MaintainTransactionPool<C>
|
||||
+ OffchainWorker<C>
|
||||
+ InitialSessionKeys<C>
|
||||
{}
|
||||
impl<C: Components, T> ServiceTrait<C> for T where
|
||||
T: Deref<Target = Service<C>>
|
||||
@@ -285,6 +300,7 @@ impl<C: Components, T> ServiceTrait<C> for T where
|
||||
+ StartRPC<C>
|
||||
+ MaintainTransactionPool<C>
|
||||
+ OffchainWorker<C>
|
||||
+ InitialSessionKeys<C>
|
||||
{}
|
||||
|
||||
/// Alias for a an implementation of `futures::future::Executor`.
|
||||
@@ -294,10 +310,6 @@ pub type TaskExecutor = Arc<dyn Executor<Box<dyn Future<Item = (), Error = ()> +
|
||||
pub trait ServiceFactory: 'static + Sized {
|
||||
/// Block type.
|
||||
type Block: BlockT<Hash=H256>;
|
||||
/// Consensus crypto type.
|
||||
type ConsensusPair: Pair;
|
||||
/// Finality crypto type.
|
||||
type FinalityPair: Pair;
|
||||
/// The type that implements the runtime API.
|
||||
type RuntimeApi: Send + Sync;
|
||||
/// Network protocol extensions.
|
||||
@@ -412,6 +424,7 @@ pub trait Components: Sized + 'static {
|
||||
fn build_client(
|
||||
config: &FactoryFullConfiguration<Self::Factory>,
|
||||
executor: CodeExecutor<Self::Factory>,
|
||||
keystore: Option<BareCryptoStorePtr>,
|
||||
) -> Result<
|
||||
(
|
||||
Arc<ComponentClient<Self>>,
|
||||
@@ -498,11 +511,11 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
|
||||
fn build_client(
|
||||
config: &FactoryFullConfiguration<Factory>,
|
||||
executor: CodeExecutor<Self::Factory>,
|
||||
)
|
||||
-> Result<(
|
||||
Arc<ComponentClient<Self>>,
|
||||
Option<Arc<OnDemand<FactoryBlock<Self::Factory>>>>
|
||||
), error::Error>
|
||||
keystore: Option<BareCryptoStorePtr>,
|
||||
) -> Result<
|
||||
(Arc<ComponentClient<Self>>, Option<Arc<OnDemand<FactoryBlock<Self::Factory>>>>),
|
||||
error::Error,
|
||||
>
|
||||
{
|
||||
let db_settings = client_db::DatabaseSettings {
|
||||
cache_size: config.database_cache_size.map(|u| u as usize),
|
||||
@@ -512,12 +525,19 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
|
||||
path: config.database_path.clone(),
|
||||
pruning: config.pruning.clone(),
|
||||
};
|
||||
Ok((Arc::new(client_db::new_client(
|
||||
db_settings,
|
||||
executor,
|
||||
&config.chain_spec,
|
||||
config.execution_strategies.clone(),
|
||||
)?), None))
|
||||
|
||||
Ok((
|
||||
Arc::new(
|
||||
client_db::new_client(
|
||||
db_settings,
|
||||
executor,
|
||||
&config.chain_spec,
|
||||
config.execution_strategies.clone(),
|
||||
keystore,
|
||||
)?
|
||||
),
|
||||
None,
|
||||
))
|
||||
}
|
||||
|
||||
fn build_transaction_pool(
|
||||
@@ -600,6 +620,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
|
||||
fn build_client(
|
||||
config: &FactoryFullConfiguration<Factory>,
|
||||
executor: CodeExecutor<Self::Factory>,
|
||||
_: Option<BareCryptoStorePtr>,
|
||||
)
|
||||
-> Result<
|
||||
(
|
||||
@@ -615,9 +636,12 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
|
||||
path: config.database_path.clone(),
|
||||
pruning: config.pruning.clone(),
|
||||
};
|
||||
|
||||
let db_storage = client_db::light::LightStorage::new(db_settings)?;
|
||||
let light_blockchain = client::light::new_light_blockchain(db_storage);
|
||||
let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone()));
|
||||
let fetch_checker = Arc::new(
|
||||
client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())
|
||||
);
|
||||
let fetcher = Arc::new(network::OnDemand::new(fetch_checker));
|
||||
let client_backend = client::light::new_light_backend(light_blockchain, fetcher.clone());
|
||||
let client = client::light::new_light(client_backend, fetcher.clone(), &config.chain_spec, executor)?;
|
||||
|
||||
@@ -31,7 +31,7 @@ use tel::TelemetryEndpoints;
|
||||
|
||||
/// Service configuration.
|
||||
#[derive(Clone)]
|
||||
pub struct Configuration<C, G: Serialize + DeserializeOwned + BuildStorage> {
|
||||
pub struct Configuration<C, G> {
|
||||
/// Implementation name
|
||||
pub impl_name: &'static str,
|
||||
/// Implementation version
|
||||
@@ -45,7 +45,7 @@ pub struct Configuration<C, G: Serialize + DeserializeOwned + BuildStorage> {
|
||||
/// Network configuration.
|
||||
pub network: NetworkConfiguration,
|
||||
/// Path to key files.
|
||||
pub keystore_path: Option<PathBuf>,
|
||||
pub keystore_path: PathBuf,
|
||||
/// Path to the database.
|
||||
pub database_path: PathBuf,
|
||||
/// Cache Size for internal database in MiB
|
||||
@@ -56,8 +56,6 @@ pub struct Configuration<C, G: Serialize + DeserializeOwned + BuildStorage> {
|
||||
pub state_cache_child_ratio: Option<usize>,
|
||||
/// Pruning settings.
|
||||
pub pruning: PruningMode,
|
||||
/// Additional key seeds.
|
||||
pub keys: Vec<String>,
|
||||
/// Chain configuration.
|
||||
pub chain_spec: ChainSpec<G>,
|
||||
/// Custom configuration.
|
||||
@@ -91,7 +89,13 @@ pub struct Configuration<C, G: Serialize + DeserializeOwned + BuildStorage> {
|
||||
/// running a sentry node in front of a validator, thus needing to forward GRANDPA gossip messages.
|
||||
pub grandpa_voter: bool,
|
||||
/// Node keystore's password
|
||||
pub password: Protected<String>,
|
||||
pub keystore_password: Option<Protected<String>>,
|
||||
/// Development key seed.
|
||||
///
|
||||
/// When running in development mode, the seed will be used to generate authority keys by the keystore.
|
||||
///
|
||||
/// Should only be set when `node` is running development mode.
|
||||
pub dev_key_seed: Option<String>,
|
||||
}
|
||||
|
||||
impl<C: Default, G: Serialize + DeserializeOwned + BuildStorage> Configuration<C, G> {
|
||||
@@ -111,7 +115,6 @@ impl<C: Default, G: Serialize + DeserializeOwned + BuildStorage> Configuration<C
|
||||
database_cache_size: Default::default(),
|
||||
state_cache_size: Default::default(),
|
||||
state_cache_child_ratio: Default::default(),
|
||||
keys: Default::default(),
|
||||
custom: Default::default(),
|
||||
pruning: PruningMode::default(),
|
||||
execution_strategies: Default::default(),
|
||||
@@ -126,7 +129,8 @@ impl<C: Default, G: Serialize + DeserializeOwned + BuildStorage> Configuration<C
|
||||
force_authoring: false,
|
||||
disable_grandpa: false,
|
||||
grandpa_voter: false,
|
||||
password: "".to_string().into(),
|
||||
keystore_password: None,
|
||||
dev_key_seed: None,
|
||||
};
|
||||
configuration.network.boot_nodes = configuration.chain_spec.boot_nodes().to_vec();
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ pub mod chain_ops;
|
||||
pub mod error;
|
||||
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::collections::HashMap;
|
||||
use std::time::{Duration, Instant};
|
||||
@@ -41,9 +40,8 @@ use keystore::Store as Keystore;
|
||||
use network::{NetworkState, NetworkStateInfo};
|
||||
use log::{log, info, warn, debug, error, Level};
|
||||
use codec::{Encode, Decode};
|
||||
use primitives::{Pair, ed25519, sr25519, crypto};
|
||||
use sr_primitives::generic::BlockId;
|
||||
use sr_primitives::traits::{Header, NumberFor, SaturatedConversion, Zero};
|
||||
use sr_primitives::traits::{Header, NumberFor, SaturatedConversion};
|
||||
use substrate_executor::NativeExecutor;
|
||||
use sysinfo::{get_current_pid, ProcessExt, System, SystemExt};
|
||||
use tel::{telemetry, SUBSTRATE_INFO};
|
||||
@@ -57,13 +55,12 @@ pub use transaction_pool::txpool::{
|
||||
pub use client::FinalityNotifications;
|
||||
|
||||
pub use components::{
|
||||
ServiceFactory, FullBackend, FullExecutor, LightBackend, ComponentAuthorityKeyProvider,
|
||||
ServiceFactory, FullBackend, FullExecutor, LightBackend,
|
||||
LightExecutor, Components, PoolApi, ComponentClient, ComponentOffchainStorage,
|
||||
ComponentBlock, FullClient, LightClient, FullComponents, LightComponents,
|
||||
CodeExecutor, NetworkService, FactoryChainSpec, FactoryBlock,
|
||||
FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis,
|
||||
ComponentExHash, ComponentExtrinsic, FactoryExtrinsic,
|
||||
ComponentConsensusPair, ComponentFinalityPair,
|
||||
ComponentExHash, ComponentExtrinsic, FactoryExtrinsic, InitialSessionKeys,
|
||||
};
|
||||
use components::{StartRPC, MaintainTransactionPool, OffchainWorker};
|
||||
#[doc(hidden)]
|
||||
@@ -85,8 +82,7 @@ pub struct Service<Components: components::Components> {
|
||||
NetworkStatus<ComponentBlock<Components>>, NetworkState
|
||||
)>>>>,
|
||||
transaction_pool: Arc<TransactionPool<Components::TransactionPoolApi>>,
|
||||
keystore: ComponentAuthorityKeyProvider<Components>,
|
||||
exit: ::exit_future::Exit,
|
||||
exit: exit_future::Exit,
|
||||
signal: Option<Signal>,
|
||||
/// Sender for futures that must be spawned as background tasks.
|
||||
to_spawn_tx: mpsc::UnboundedSender<Box<dyn Future<Item = (), Error = ()> + Send>>,
|
||||
@@ -105,21 +101,22 @@ pub struct Service<Components: components::Components> {
|
||||
_offchain_workers: Option<Arc<offchain::OffchainWorkers<
|
||||
ComponentClient<Components>,
|
||||
ComponentOffchainStorage<Components>,
|
||||
ComponentAuthorityKeyProvider<Components>,
|
||||
ComponentBlock<Components>>
|
||||
>>,
|
||||
keystore: keystore::KeyStorePtr,
|
||||
}
|
||||
|
||||
/// Creates bare client without any networking.
|
||||
pub fn new_client<Factory: components::ServiceFactory>(config: &FactoryFullConfiguration<Factory>)
|
||||
-> Result<Arc<ComponentClient<components::FullComponents<Factory>>>, error::Error>
|
||||
{
|
||||
pub fn new_client<Factory: components::ServiceFactory>(
|
||||
config: &FactoryFullConfiguration<Factory>,
|
||||
) -> Result<Arc<ComponentClient<components::FullComponents<Factory>>>, error::Error> {
|
||||
let executor = NativeExecutor::new(config.default_heap_pages);
|
||||
let (client, _) = components::FullComponents::<Factory>::build_client(
|
||||
|
||||
components::FullComponents::<Factory>::build_client(
|
||||
config,
|
||||
executor,
|
||||
)?;
|
||||
Ok(client)
|
||||
None,
|
||||
).map(|r| r.0)
|
||||
}
|
||||
|
||||
/// An handle for spawning tasks in the service.
|
||||
@@ -172,43 +169,9 @@ impl<Components: components::Components> Service<Components> {
|
||||
// Create client
|
||||
let executor = NativeExecutor::new(config.default_heap_pages);
|
||||
|
||||
let mut keystore = if let Some(keystore_path) = config.keystore_path.as_ref() {
|
||||
match Keystore::open(keystore_path.clone()) {
|
||||
Ok(ks) => Some(ks),
|
||||
Err(err) => {
|
||||
error!("Failed to initialize keystore: {}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?;
|
||||
|
||||
// Keep the public key for telemetry
|
||||
let public_key: String;
|
||||
|
||||
// This is meant to be for testing only
|
||||
// FIXME #1063 remove this
|
||||
if let Some(keystore) = keystore.as_mut() {
|
||||
for seed in &config.keys {
|
||||
keystore.generate_from_seed::<ed25519::Pair>(seed)?;
|
||||
keystore.generate_from_seed::<sr25519::Pair>(seed)?;
|
||||
}
|
||||
|
||||
public_key = match keystore.contents::<ed25519::Public>()?.get(0) {
|
||||
Some(public_key) => public_key.to_string(),
|
||||
None => {
|
||||
let key: ed25519::Pair = keystore.generate(&config.password.as_ref())?;
|
||||
let public_key = key.public();
|
||||
info!("Generated a new keypair: {:?}", public_key);
|
||||
public_key.to_string()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
public_key = format!("<disabled-keystore>");
|
||||
}
|
||||
|
||||
let (client, on_demand) = Components::build_client(&config, executor)?;
|
||||
let (client, on_demand) = Components::build_client(&config, executor, Some(keystore.clone()))?;
|
||||
let select_chain = Components::build_select_chain(&mut config, client.clone())?;
|
||||
let (import_queue, finality_proof_request_builder) = Components::build_import_queue(
|
||||
&mut config,
|
||||
@@ -219,9 +182,16 @@ impl<Components: components::Components> Service<Components> {
|
||||
let finality_proof_provider = Components::build_finality_proof_provider(client.clone())?;
|
||||
let chain_info = client.info().chain;
|
||||
|
||||
Components::RuntimeServices::generate_intial_session_keys(
|
||||
client.clone(),
|
||||
config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(),
|
||||
)?;
|
||||
|
||||
let version = config.full_version();
|
||||
info!("Highest known block at #{}", chain_info.best_number);
|
||||
telemetry!(SUBSTRATE_INFO; "node.start";
|
||||
telemetry!(
|
||||
SUBSTRATE_INFO;
|
||||
"node.start";
|
||||
"height" => chain_info.best_number.saturated_into::<u64>(),
|
||||
"best" => ?chain_info.best_hash
|
||||
);
|
||||
@@ -234,7 +204,7 @@ impl<Components: components::Components> Service<Components> {
|
||||
imports_external_transactions: !config.roles.is_light(),
|
||||
pool: transaction_pool.clone(),
|
||||
client: client.clone(),
|
||||
});
|
||||
});
|
||||
|
||||
let protocol_id = {
|
||||
let protocol_id_full = match config.chain_spec.protocol_id() {
|
||||
@@ -267,23 +237,11 @@ impl<Components: components::Components> Service<Components> {
|
||||
let network = network_mut.service().clone();
|
||||
let network_status_sinks = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let keystore_authority_key = AuthorityKeyProvider {
|
||||
_marker: PhantomData,
|
||||
roles: config.roles,
|
||||
password: config.password.clone(),
|
||||
keystore: keystore.map(Arc::new),
|
||||
};
|
||||
|
||||
#[allow(deprecated)]
|
||||
let offchain_storage = client.backend().offchain_storage();
|
||||
let offchain_workers = match (config.offchain_worker, offchain_storage) {
|
||||
(true, Some(db)) => {
|
||||
Some(Arc::new(offchain::OffchainWorkers::new(
|
||||
client.clone(),
|
||||
db,
|
||||
keystore_authority_key.clone(),
|
||||
config.password.clone(),
|
||||
)))
|
||||
Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db)))
|
||||
},
|
||||
(true, None) => {
|
||||
log::warn!("Offchain workers disabled, due to lack of offchain storage support in backend.");
|
||||
@@ -421,6 +379,7 @@ impl<Components: components::Components> Service<Components> {
|
||||
system_info.clone(),
|
||||
Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }),
|
||||
transaction_pool.clone(),
|
||||
keystore.clone(),
|
||||
)
|
||||
};
|
||||
let rpc_handlers = gen_handler();
|
||||
@@ -465,7 +424,6 @@ impl<Components: components::Components> Service<Components> {
|
||||
"version" => version.clone(),
|
||||
"config" => "",
|
||||
"chain" => chain_name.clone(),
|
||||
"pubkey" => &public_key,
|
||||
"authority" => is_authority,
|
||||
"network_id" => network_id.clone()
|
||||
);
|
||||
@@ -491,7 +449,6 @@ impl<Components: components::Components> Service<Components> {
|
||||
to_spawn_tx,
|
||||
to_spawn_rx,
|
||||
to_poll: Vec::new(),
|
||||
keystore: keystore_authority_key,
|
||||
config,
|
||||
exit,
|
||||
rpc_handlers,
|
||||
@@ -499,28 +456,20 @@ impl<Components: components::Components> Service<Components> {
|
||||
_telemetry: telemetry,
|
||||
_offchain_workers: offchain_workers,
|
||||
_telemetry_on_connect_sinks: telemetry_connection_sinks.clone(),
|
||||
keystore,
|
||||
})
|
||||
}
|
||||
|
||||
/// give the authority key, if we are an authority and have a key
|
||||
pub fn authority_key(&self) -> Option<ComponentConsensusPair<Components>> {
|
||||
use offchain::AuthorityKeyProvider;
|
||||
|
||||
self.keystore.authority_key(&BlockId::Number(Zero::zero()))
|
||||
}
|
||||
|
||||
/// give the authority key, if we are an authority and have a key
|
||||
pub fn fg_authority_key(&self) -> Option<ComponentFinalityPair<Components>> {
|
||||
use offchain::AuthorityKeyProvider;
|
||||
|
||||
self.keystore.fg_authority_key(&BlockId::Number(Zero::zero()))
|
||||
}
|
||||
|
||||
/// return a shared instance of Telemetry (if enabled)
|
||||
/// Return a shared instance of Telemetry (if enabled)
|
||||
pub fn telemetry(&self) -> Option<tel::Telemetry> {
|
||||
self._telemetry.as_ref().map(|t| t.clone())
|
||||
}
|
||||
|
||||
/// Returns the keystore instance.
|
||||
pub fn keystore(&self) -> keystore::KeyStorePtr {
|
||||
self.keystore.clone()
|
||||
}
|
||||
|
||||
/// Spawns a task in the background that runs the future passed as parameter.
|
||||
pub fn spawn_task(&self, task: impl Future<Item = (), Error = ()> + Send + 'static) {
|
||||
let _ = self.to_spawn_tx.unbounded_send(Box::new(task));
|
||||
@@ -910,73 +859,6 @@ impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
/// A provider of current authority key.
|
||||
pub struct AuthorityKeyProvider<Block, ConsensusPair, FinalityPair> {
|
||||
_marker: PhantomData<(Block, ConsensusPair, FinalityPair)>,
|
||||
roles: Roles,
|
||||
keystore: Option<Arc<Keystore>>,
|
||||
password: crypto::Protected<String>,
|
||||
}
|
||||
|
||||
impl<Block, ConsensusPair, FinalityPair>
|
||||
offchain::AuthorityKeyProvider<Block>
|
||||
for AuthorityKeyProvider<Block, ConsensusPair, FinalityPair>
|
||||
where
|
||||
Block: sr_primitives::traits::Block,
|
||||
ConsensusPair: Pair,
|
||||
FinalityPair: Pair,
|
||||
{
|
||||
type ConsensusPair = ConsensusPair;
|
||||
type FinalityPair = FinalityPair;
|
||||
|
||||
fn authority_key(&self, _at: &BlockId<Block>) -> Option<Self::ConsensusPair> {
|
||||
if self.roles != Roles::AUTHORITY {
|
||||
return None
|
||||
}
|
||||
|
||||
let keystore = match self.keystore {
|
||||
Some(ref keystore) => keystore,
|
||||
None => return None
|
||||
};
|
||||
|
||||
let loaded_key = keystore
|
||||
.contents()
|
||||
.map(|keys| keys.get(0)
|
||||
.map(|k| keystore.load(k, self.password.as_ref()))
|
||||
);
|
||||
|
||||
if let Ok(Some(Ok(key))) = loaded_key {
|
||||
Some(key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn fg_authority_key(&self, _at: &BlockId<Block>) -> Option<Self::FinalityPair> {
|
||||
if self.roles != Roles::AUTHORITY {
|
||||
return None
|
||||
}
|
||||
|
||||
let keystore = match self.keystore {
|
||||
Some(ref keystore) => keystore,
|
||||
None => return None
|
||||
};
|
||||
|
||||
let loaded_key = keystore
|
||||
.contents()
|
||||
.map(|keys| keys.get(0)
|
||||
.map(|k| keystore.load(k, self.password.as_ref()))
|
||||
);
|
||||
|
||||
if let Ok(Some(Ok(key))) = loaded_key {
|
||||
Some(key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a service factory with the given name that implements the `ServiceFactory` trait.
|
||||
/// The required parameters are required to be given in the exact order. Some parameters are followed
|
||||
/// by `{}` blocks. These blocks are required and used to initialize the given parameter.
|
||||
@@ -998,6 +880,8 @@ where
|
||||
/// # use node_runtime::{GenesisConfig, RuntimeApi};
|
||||
/// # use std::sync::Arc;
|
||||
/// # use node_primitives::Block;
|
||||
/// # use babe_primitives::AuthorityPair as BabePair;
|
||||
/// # use grandpa_primitives::AuthorityPair as GrandpaPair;
|
||||
/// # use sr_primitives::Justification;
|
||||
/// # use sr_primitives::traits::Block as BlockT;
|
||||
/// # use grandpa;
|
||||
@@ -1025,8 +909,6 @@ where
|
||||
/// struct Factory {
|
||||
/// // Declare the block type
|
||||
/// Block = Block,
|
||||
/// ConsensusPair = primitives::ed25519::Pair,
|
||||
/// FinalityPair = primitives::ed25519::Pair,
|
||||
/// RuntimeApi = RuntimeApi,
|
||||
/// // Declare the network protocol and give an initializer.
|
||||
/// NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) },
|
||||
@@ -1070,8 +952,6 @@ macro_rules! construct_service_factory {
|
||||
$(#[$attr:meta])*
|
||||
struct $name:ident {
|
||||
Block = $block:ty,
|
||||
ConsensusPair = $consensus_pair:ty,
|
||||
FinalityPair = $finality_pair:ty,
|
||||
RuntimeApi = $runtime_api:ty,
|
||||
NetworkProtocol = $protocol:ty { $( $protocol_init:tt )* },
|
||||
RuntimeDispatch = $dispatch:ty,
|
||||
@@ -1097,8 +977,6 @@ macro_rules! construct_service_factory {
|
||||
#[allow(unused_variables)]
|
||||
impl $crate::ServiceFactory for $name {
|
||||
type Block = $block;
|
||||
type ConsensusPair = $consensus_pair;
|
||||
type FinalityPair = $finality_pair;
|
||||
type RuntimeApi = $runtime_api;
|
||||
type NetworkProtocol = $protocol;
|
||||
type RuntimeDispatch = $dispatch;
|
||||
|
||||
Reference in New Issue
Block a user