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:
Gavin Wood
2019-08-07 20:47:48 +02:00
committed by GitHub
parent a6a6779f01
commit 1a524b8207
160 changed files with 4467 additions and 2769 deletions
+3 -3
View File
@@ -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(),
+56 -32
View File
@@ -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)?;
+11 -7
View File
@@ -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();
+34 -156
View File
@@ -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;