Keystore overhaul (iter 2) (#13634)

* Remove bloat about remote keystore

* Update docs and remove unused 'KeystoreRef' trait

* Use wherever possible, MemoryKeystore for testing

* Remove unrequired fully qualified method syntax for Keystore
This commit is contained in:
Davide Galassi
2023-03-20 19:21:26 +01:00
committed by GitHub
parent faaa0c2851
commit 480396fe06
44 changed files with 312 additions and 457 deletions
@@ -697,7 +697,7 @@ fn addresses_to_publish_adds_p2p() {
Arc::new(TestApi { authorities: vec![] }),
network.clone(),
Box::pin(dht_event_rx),
Role::PublishAndDiscover(Arc::new(MemoryKeystore::new())),
Role::PublishAndDiscover(MemoryKeystore::new().into()),
Some(prometheus_endpoint::Registry::new()),
Default::default(),
);
@@ -731,7 +731,7 @@ fn addresses_to_publish_respects_existing_p2p_protocol() {
Arc::new(TestApi { authorities: vec![] }),
network.clone(),
Box::pin(dht_event_rx),
Role::PublishAndDiscover(Arc::new(MemoryKeystore::new())),
Role::PublishAndDiscover(MemoryKeystore::new().into()),
Some(prometheus_endpoint::Registry::new()),
Default::default(),
);
@@ -24,8 +24,7 @@ use clap::Parser;
use sc_keystore::LocalKeystore;
use sc_service::config::{BasePath, KeystoreConfig};
use sp_core::crypto::{KeyTypeId, SecretString};
use sp_keystore::{Keystore, KeystorePtr};
use std::sync::Arc;
use sp_keystore::KeystorePtr;
/// The `insert` command
#[derive(Debug, Clone, Parser)]
@@ -67,9 +66,9 @@ impl InsertKeyCmd {
let config_dir = base_path.config_dir(chain_spec.id());
let (keystore, public) = match self.keystore_params.keystore_config(&config_dir)? {
(_, KeystoreConfig::Path { path, password }) => {
KeystoreConfig::Path { path, password } => {
let public = with_crypto_scheme!(self.scheme, to_vec(&suri, password.clone()))?;
let keystore: KeystorePtr = Arc::new(LocalKeystore::open(path, password)?);
let keystore: KeystorePtr = LocalKeystore::open(path, password)?.into();
(keystore, public)
},
_ => unreachable!("keystore_config always returns path and password; qed"),
@@ -78,7 +77,8 @@ impl InsertKeyCmd {
let key_type =
KeyTypeId::try_from(self.key_type.as_str()).map_err(|_| Error::KeyTypeInvalid)?;
Keystore::insert(&*keystore, key_type, &suri, &public[..])
keystore
.insert(key_type, &suri, &public[..])
.map_err(|_| Error::KeystoreOperation)?;
Ok(())
@@ -95,6 +95,7 @@ mod tests {
use super::*;
use sc_service::{ChainSpec, ChainType, GenericChainSpec, NoExtension};
use sp_core::{sr25519::Pair, ByteArray, Pair as _};
use sp_keystore::Keystore;
use tempfile::TempDir;
struct Cli;
+3 -4
View File
@@ -185,10 +185,10 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
///
/// By default this is retrieved from `KeystoreParams` if it is available. Otherwise it uses
/// `KeystoreConfig::InMemory`.
fn keystore_config(&self, config_dir: &PathBuf) -> Result<(Option<String>, KeystoreConfig)> {
fn keystore_config(&self, config_dir: &PathBuf) -> Result<KeystoreConfig> {
self.keystore_params()
.map(|x| x.keystore_config(config_dir))
.unwrap_or_else(|| Ok((None, KeystoreConfig::InMemory)))
.unwrap_or_else(|| Ok(KeystoreConfig::InMemory))
}
/// Get the database cache size.
@@ -505,7 +505,7 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
let role = self.role(is_dev)?;
let max_runtime_instances = self.max_runtime_instances()?.unwrap_or(8);
let is_validator = role.is_authority();
let (keystore_remote, keystore) = self.keystore_config(&config_dir)?;
let keystore = self.keystore_config(&config_dir)?;
let telemetry_endpoints = self.telemetry_endpoints(&chain_spec)?;
let runtime_cache_size = self.runtime_cache_size()?;
@@ -524,7 +524,6 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
node_key,
DCV::p2p_listen_port(),
)?,
keystore_remote,
keystore,
database: self.database_config(&config_dir, database_cache_size, database)?,
trie_cache_maximum_size: self.trie_cache_maximum_size()?,
@@ -68,9 +68,7 @@ pub fn secret_string_from_str(s: &str) -> std::result::Result<SecretString, Stri
impl KeystoreParams {
/// Get the keystore configuration for the parameters
///
/// Returns a vector of remote-urls and the local Keystore configuration
pub fn keystore_config(&self, config_dir: &Path) -> Result<(Option<String>, KeystoreConfig)> {
pub fn keystore_config(&self, config_dir: &Path) -> Result<KeystoreConfig> {
let password = if self.password_interactive {
Some(SecretString::new(input_keystore_password()?))
} else if let Some(ref file) = self.password_filename {
@@ -85,7 +83,7 @@ impl KeystoreParams {
.clone()
.unwrap_or_else(|| config_dir.join(DEFAULT_KEYSTORE_CONFIG_PATH));
Ok((self.keystore_uri.clone(), KeystoreConfig::Path { path, password }))
Ok(KeystoreConfig::Path { path, password })
}
/// helper method to fetch password from `KeyParams` or read from stdin
-1
View File
@@ -345,7 +345,6 @@ mod tests {
transaction_pool: Default::default(),
network: NetworkConfiguration::new_memory(),
keystore: sc_service::config::KeystoreConfig::InMemory,
keystore_remote: None,
database: sc_client_db::DatabaseSource::ParityDb { path: PathBuf::from("db") },
trie_cache_maximum_size: None,
state_pruning: None,
+23 -26
View File
@@ -51,7 +51,7 @@ use sp_consensus::{BlockOrigin, Environment, Error as ConsensusError, Proposer,
use sp_consensus_slots::Slot;
use sp_core::crypto::{ByteArray, Pair, Public};
use sp_inherents::CreateInherentDataProviders;
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use sp_runtime::{
traits::{Block as BlockT, Header, Member, NumberFor, Zero},
DigestItem,
@@ -418,10 +418,10 @@ where
) -> Option<Self::Claim> {
let expected_author = slot_author::<P>(slot, epoch_data);
expected_author.and_then(|p| {
if Keystore::has_keys(
&*self.keystore,
&[(p.to_raw_vec(), sp_application_crypto::key_types::AURA)],
) {
if self
.keystore
.has_keys(&[(p.to_raw_vec(), sp_application_crypto::key_types::AURA)])
{
Some(p.clone())
} else {
None
@@ -449,19 +449,16 @@ where
// add it to a digest item.
let public_type_pair = public.to_public_crypto_pair();
let public = public.to_raw_vec();
let signature = Keystore::sign_with(
&*self.keystore,
<AuthorityId<P> as AppKey>::ID,
&public_type_pair,
header_hash.as_ref(),
)
.map_err(|e| sp_consensus::Error::CannotSign(public.clone(), e.to_string()))?
.ok_or_else(|| {
sp_consensus::Error::CannotSign(
public.clone(),
"Could not find key in keystore.".into(),
)
})?;
let signature = self
.keystore
.sign_with(<AuthorityId<P> as AppKey>::ID, &public_type_pair, header_hash.as_ref())
.map_err(|e| sp_consensus::Error::CannotSign(public.clone(), e.to_string()))?
.ok_or_else(|| {
sp_consensus::Error::CannotSign(
public.clone(),
"Could not find key in keystore.".into(),
)
})?;
let signature = signature
.clone()
.try_into()
@@ -648,6 +645,7 @@ mod tests {
use sp_consensus_aura::sr25519::AuthorityPair;
use sp_inherents::InherentData;
use sp_keyring::sr25519::Keyring;
use sp_keystore::Keystore;
use sp_runtime::{
traits::{Block as BlockT, Header as _},
Digest,
@@ -798,7 +796,8 @@ mod tests {
LocalKeystore::open(keystore_path.path(), None).expect("Creates keystore."),
);
Keystore::sr25519_generate_new(&*keystore, AURA, Some(&key.to_seed()))
keystore
.sr25519_generate_new(AURA, Some(&key.to_seed()))
.expect("Creates authority key");
keystore_paths.push(keystore_path);
@@ -883,7 +882,8 @@ mod tests {
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
let keystore = LocalKeystore::open(keystore_path.path(), None).expect("Creates keystore.");
let public = Keystore::sr25519_generate_new(&keystore, AuthorityPair::ID, None)
let public = keystore
.sr25519_generate_new(AuthorityPair::ID, None)
.expect("Key should be created");
authorities.push(public.into());
@@ -933,12 +933,9 @@ mod tests {
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
let keystore = LocalKeystore::open(keystore_path.path(), None).expect("Creates keystore.");
Keystore::sr25519_generate_new(
&keystore,
AuthorityPair::ID,
Some(&Keyring::Alice.to_seed()),
)
.expect("Key should be created");
keystore
.sr25519_generate_new(AuthorityPair::ID, Some(&Keyring::Alice.to_seed()))
.expect("Key should be created");
let net = Arc::new(Mutex::new(net));
@@ -31,7 +31,6 @@ sp-runtime = { version = "7.0.0", path = "../../../../primitives/runtime" }
[dev-dependencies]
serde_json = "1.0.85"
tempfile = "3.1.0"
tokio = "1.22.0"
sc-consensus = { version = "0.10.0-dev", path = "../../../consensus/common" }
sc-keystore = { version = "4.0.0-dev", path = "../../../keystore" }
+10 -19
View File
@@ -37,7 +37,7 @@ use sp_consensus_babe::{
digests::PreDigest, AuthorityId, BabeApi as BabeRuntimeApi, BabeConfiguration,
};
use sp_core::crypto::ByteArray;
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use sp_runtime::traits::{Block as BlockT, Header as _};
use std::{collections::HashMap, sync::Arc};
@@ -117,7 +117,7 @@ where
.iter()
.enumerate()
.filter_map(|(i, a)| {
if Keystore::has_keys(&*self.keystore, &[(a.0.to_raw_vec(), AuthorityId::ID)]) {
if self.keystore.has_keys(&[(a.0.to_raw_vec(), AuthorityId::ID)]) {
Some((a.0.clone(), i))
} else {
None
@@ -210,30 +210,21 @@ where
#[cfg(test)]
mod tests {
use super::*;
use sc_keystore::LocalKeystore;
use sp_application_crypto::AppPair;
use sc_consensus_babe::block_import;
use sp_core::crypto::key_types::BABE;
use sp_keyring::Sr25519Keyring;
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::{testing::MemoryKeystore, Keystore};
use substrate_test_runtime_client::{
runtime::Block, Backend, DefaultTestClientBuilderExt, TestClient, TestClientBuilder,
TestClientBuilderExt,
};
use sc_consensus_babe::{block_import, AuthorityPair};
use std::sync::Arc;
/// creates keystore backed by a temp file
fn create_temp_keystore<P: AppPair>(
authority: Sr25519Keyring,
) -> (KeystorePtr, tempfile::TempDir) {
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
let keystore =
Arc::new(LocalKeystore::open(keystore_path.path(), None).expect("Creates keystore"));
Keystore::sr25519_generate_new(&*keystore, BABE, Some(&authority.to_seed()))
fn create_keystore(authority: Sr25519Keyring) -> KeystorePtr {
let keystore = MemoryKeystore::new();
keystore
.sr25519_generate_new(BABE, Some(&authority.to_seed()))
.expect("Creates authority key");
(keystore, keystore_path)
keystore.into()
}
fn test_babe_rpc_module(
@@ -247,7 +238,7 @@ mod tests {
.expect("can initialize block-import");
let epoch_changes = link.epoch_changes().clone();
let keystore = create_temp_keystore::<AuthorityPair>(Sr25519Keyring::Alice).0;
let keystore = create_keystore(Sr25519Keyring::Alice);
Babe::new(client.clone(), epoch_changes, keystore, config, longest_chain, deny_unsafe)
}
@@ -29,7 +29,7 @@ use sp_consensus_babe::{
};
use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof};
use sp_core::{blake2_256, crypto::ByteArray, U256};
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
/// Calculates the primary selection threshold for a given authority, taking
/// into account `c` (`1 - c` represents the probability of a slot being empty).
@@ -153,8 +153,7 @@ fn claim_secondary_slot(
if authority_id == expected_author {
let pre_digest = if author_secondary_vrf {
let transcript_data = make_transcript_data(randomness, slot, epoch_index);
let result = Keystore::sr25519_vrf_sign(
&**keystore,
let result = keystore.sr25519_vrf_sign(
AuthorityId::ID,
authority_id.as_ref(),
transcript_data,
@@ -169,10 +168,7 @@ fn claim_secondary_slot(
} else {
None
}
} else if Keystore::has_keys(
&**keystore,
&[(authority_id.to_raw_vec(), AuthorityId::ID)],
) {
} else if keystore.has_keys(&[(authority_id.to_raw_vec(), AuthorityId::ID)]) {
Some(PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot,
authority_index: *authority_index as u32,
@@ -254,12 +250,8 @@ fn claim_primary_slot(
for (authority_id, authority_index) in keys {
let transcript = make_transcript(randomness, slot, epoch_index);
let transcript_data = make_transcript_data(randomness, slot, epoch_index);
let result = Keystore::sr25519_vrf_sign(
&**keystore,
AuthorityId::ID,
authority_id.as_ref(),
transcript_data,
);
let result =
keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), transcript_data);
if let Ok(Some(signature)) = result {
let public = PublicKey::from_bytes(&authority_id.to_raw_vec()).ok()?;
let inout = match signature.output.attach_input_hash(&public, transcript) {
@@ -287,20 +279,16 @@ fn claim_primary_slot(
#[cfg(test)]
mod tests {
use super::*;
use sc_keystore::LocalKeystore;
use sp_consensus_babe::{AllowedSlots, AuthorityId, BabeEpochConfiguration};
use sp_core::{crypto::Pair as _, sr25519::Pair};
use std::sync::Arc;
use sp_keystore::testing::MemoryKeystore;
#[test]
fn claim_secondary_plain_slot_works() {
let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory());
let valid_public_key = Keystore::sr25519_generate_new(
&*keystore,
AuthorityId::ID,
Some(sp_core::crypto::DEV_PHRASE),
)
.unwrap();
let keystore: KeystorePtr = MemoryKeystore::new().into();
let valid_public_key = keystore
.sr25519_generate_new(AuthorityId::ID, Some(sp_core::crypto::DEV_PHRASE))
.unwrap();
let authorities = vec![
(AuthorityId::from(Pair::generate().0.public()), 5),
+11 -14
View File
@@ -119,7 +119,7 @@ use sp_consensus_babe::inherents::BabeInherentData;
use sp_consensus_slots::Slot;
use sp_core::{crypto::ByteArray, ExecutionContext};
use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider};
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use sp_runtime::{
generic::OpaqueDigestItemId,
traits::{Block as BlockT, Header, NumberFor, SaturatedConversion, Zero},
@@ -834,19 +834,16 @@ where
// add it to a digest item.
let public_type_pair = public.clone().into();
let public = public.to_raw_vec();
let signature = Keystore::sign_with(
&*self.keystore,
<AuthorityId as AppKey>::ID,
&public_type_pair,
header_hash.as_ref(),
)
.map_err(|e| sp_consensus::Error::CannotSign(public.clone(), e.to_string()))?
.ok_or_else(|| {
sp_consensus::Error::CannotSign(
public.clone(),
"Could not find key in keystore.".into(),
)
})?;
let signature = self
.keystore
.sign_with(<AuthorityId as AppKey>::ID, &public_type_pair, header_hash.as_ref())
.map_err(|e| sp_consensus::Error::CannotSign(public.clone(), e.to_string()))?
.ok_or_else(|| {
sp_consensus::Error::CannotSign(
public.clone(),
"Could not find key in keystore.".into(),
)
})?;
let signature: AuthoritySignature = signature
.clone()
.try_into()
+12 -7
View File
@@ -369,10 +369,11 @@ async fn rejects_empty_block() {
}
fn create_keystore(authority: Sr25519Keyring) -> KeystorePtr {
let keystore = Arc::new(MemoryKeystore::new());
Keystore::sr25519_generate_new(&*keystore, BABE, Some(&authority.to_seed()))
.expect("Generates authority key");
let keystore = MemoryKeystore::new();
keystore
.sr25519_generate_new(BABE, Some(&authority.to_seed()))
.expect("Generates authority key");
keystore.into()
}
async fn run_one_test(mutator: impl Fn(&mut TestHeader, Stage) + Send + Sync + 'static) {
@@ -637,7 +638,8 @@ fn claim_vrf_check() {
v => panic!("Unexpected pre-digest variant {:?}", v),
};
let transcript = make_transcript_data(&epoch.randomness.clone(), 0.into(), epoch.epoch_index);
let sign = Keystore::sr25519_vrf_sign(&*keystore, AuthorityId::ID, &public, transcript)
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, transcript)
.unwrap()
.unwrap();
assert_eq!(pre_digest.vrf_output, VRFOutput(sign.output));
@@ -648,7 +650,8 @@ fn claim_vrf_check() {
v => panic!("Unexpected pre-digest variant {:?}", v),
};
let transcript = make_transcript_data(&epoch.randomness.clone(), 1.into(), epoch.epoch_index);
let sign = Keystore::sr25519_vrf_sign(&*keystore, AuthorityId::ID, &public, transcript)
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, transcript)
.unwrap()
.unwrap();
assert_eq!(pre_digest.vrf_output, VRFOutput(sign.output));
@@ -661,7 +664,8 @@ fn claim_vrf_check() {
};
let fixed_epoch = epoch.clone_for_slot(slot);
let transcript = make_transcript_data(&epoch.randomness.clone(), slot, fixed_epoch.epoch_index);
let sign = Keystore::sr25519_vrf_sign(&*keystore, AuthorityId::ID, &public, transcript)
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, transcript)
.unwrap()
.unwrap();
assert_eq!(fixed_epoch.epoch_index, 11);
@@ -675,7 +679,8 @@ fn claim_vrf_check() {
};
let fixed_epoch = epoch.clone_for_slot(slot);
let transcript = make_transcript_data(&epoch.randomness.clone(), slot, fixed_epoch.epoch_index);
let sign = Keystore::sr25519_vrf_sign(&*keystore, AuthorityId::ID, &public, transcript)
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, transcript)
.unwrap()
.unwrap();
assert_eq!(fixed_epoch.epoch_index, 11);
@@ -243,17 +243,14 @@ where
#[cfg(test)]
mod tests {
use sc_keystore::LocalKeystore;
use sc_network_test::Block;
use sp_keystore::{Keystore, KeystorePtr};
use super::*;
use crate::keystore::BeefyKeystore;
use sc_network_test::Block;
use sp_consensus_beefy::{
crypto::Signature, known_payloads, Commitment, Keyring, MmrRootHash, Payload, VoteMessage,
KEY_TYPE,
};
use super::*;
use sp_keystore::{testing::MemoryKeystore, Keystore};
#[test]
fn known_votes_insert_remove() {
@@ -306,10 +303,9 @@ mod tests {
}
fn sign_commitment<BN: Encode>(who: &Keyring, commitment: &Commitment<BN>) -> Signature {
let store: KeystorePtr = std::sync::Arc::new(LocalKeystore::in_memory());
Keystore::ecdsa_generate_new(&*store, KEY_TYPE, Some(&who.to_seed())).unwrap();
let beefy_keystore: BeefyKeystore = Some(store).into();
let store = MemoryKeystore::new();
store.ecdsa_generate_new(KEY_TYPE, Some(&who.to_seed())).unwrap();
let beefy_keystore: BeefyKeystore = Some(store.into()).into();
beefy_keystore.sign(&who.public(), &commitment.encode()).unwrap()
}
@@ -18,7 +18,7 @@
use sp_application_crypto::RuntimeAppPublic;
use sp_core::keccak_256;
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use log::warn;
@@ -50,7 +50,7 @@ impl BeefyKeystore {
// we do check for multiple private keys as a key store sanity check.
let public: Vec<Public> = keys
.iter()
.filter(|k| Keystore::has_keys(&*store, &[(k.to_raw_vec(), KEY_TYPE)]))
.filter(|k| store.has_keys(&[(k.to_raw_vec(), KEY_TYPE)]))
.cloned()
.collect();
@@ -77,7 +77,8 @@ impl BeefyKeystore {
let msg = keccak_256(message);
let public = public.as_ref();
let sig = Keystore::ecdsa_sign_prehashed(&*store, KEY_TYPE, public, &msg)
let sig = store
.ecdsa_sign_prehashed(KEY_TYPE, public, &msg)
.map_err(|e| error::Error::Keystore(e.to_string()))?
.ok_or_else(|| error::Error::Signature("ecdsa_sign_prehashed() failed".to_string()))?;
@@ -94,10 +95,8 @@ impl BeefyKeystore {
pub fn public_keys(&self) -> Result<Vec<Public>, error::Error> {
let store = self.0.clone().ok_or_else(|| error::Error::Keystore("no Keystore".into()))?;
let pk: Vec<Public> = Keystore::ecdsa_public_keys(&*store, KEY_TYPE)
.drain(..)
.map(Public::from)
.collect();
let pk: Vec<Public> =
store.ecdsa_public_keys(KEY_TYPE).drain(..).map(Public::from).collect();
Ok(pk)
}
@@ -118,18 +117,15 @@ impl From<Option<KeystorePtr>> for BeefyKeystore {
#[cfg(test)]
pub mod tests {
use std::sync::Arc;
use sc_keystore::LocalKeystore;
use sp_core::{ecdsa, Pair};
use sp_consensus_beefy::{crypto, Keyring};
use sp_core::{ecdsa, Pair};
use sp_keystore::testing::MemoryKeystore;
use super::*;
use crate::error::Error;
fn keystore() -> KeystorePtr {
Arc::new(LocalKeystore::in_memory())
MemoryKeystore::new().into()
}
#[test]
@@ -197,11 +193,11 @@ pub mod tests {
fn authority_id_works() {
let store = keystore();
let alice: crypto::Public =
Keystore::ecdsa_generate_new(&*store, KEY_TYPE, Some(&Keyring::Alice.to_seed()))
.ok()
.unwrap()
.into();
let alice: crypto::Public = store
.ecdsa_generate_new(KEY_TYPE, Some(&Keyring::Alice.to_seed()))
.ok()
.unwrap()
.into();
let bob = Keyring::Bob.public();
let charlie = Keyring::Charlie.public();
@@ -223,11 +219,11 @@ pub mod tests {
fn sign_works() {
let store = keystore();
let alice: crypto::Public =
Keystore::ecdsa_generate_new(&*store, KEY_TYPE, Some(&Keyring::Alice.to_seed()))
.ok()
.unwrap()
.into();
let alice: crypto::Public = store
.ecdsa_generate_new(KEY_TYPE, Some(&Keyring::Alice.to_seed()))
.ok()
.unwrap()
.into();
let store: BeefyKeystore = Some(store).into();
@@ -243,9 +239,7 @@ pub mod tests {
fn sign_error() {
let store = keystore();
let _ = Keystore::ecdsa_generate_new(&*store, KEY_TYPE, Some(&Keyring::Bob.to_seed()))
.ok()
.unwrap();
store.ecdsa_generate_new(KEY_TYPE, Some(&Keyring::Bob.to_seed())).ok().unwrap();
let store: BeefyKeystore = Some(store).into();
@@ -274,11 +268,11 @@ pub mod tests {
fn verify_works() {
let store = keystore();
let alice: crypto::Public =
Keystore::ecdsa_generate_new(&*store, KEY_TYPE, Some(&Keyring::Alice.to_seed()))
.ok()
.unwrap()
.into();
let alice: crypto::Public = store
.ecdsa_generate_new(KEY_TYPE, Some(&Keyring::Alice.to_seed()))
.ok()
.unwrap()
.into();
let store: BeefyKeystore = Some(store).into();
@@ -300,9 +294,8 @@ pub mod tests {
let store = keystore();
let add_key = |key_type, seed: Option<&str>| {
Keystore::ecdsa_generate_new(&*store, key_type, seed).unwrap()
};
let add_key =
|key_type, seed: Option<&str>| store.ecdsa_generate_new(key_type, seed).unwrap();
// test keys
let _ = add_key(TEST_TYPE, Some(Keyring::Alice.to_seed().as_str()));
@@ -340,10 +340,11 @@ pub(crate) fn make_beefy_ids(keys: &[BeefyKeyring]) -> Vec<AuthorityId> {
}
pub(crate) fn create_beefy_keystore(authority: BeefyKeyring) -> KeystorePtr {
let keystore = Arc::new(MemoryKeystore::new());
Keystore::ecdsa_generate_new(&*keystore, BeefyKeyType, Some(&authority.to_seed()))
.expect("Creates authority key");
let keystore = MemoryKeystore::new();
keystore
.ecdsa_generate_new(BeefyKeyType, Some(&authority.to_seed()))
.expect("Creates authority key");
keystore.into()
}
async fn voter_init_setup(
@@ -79,7 +79,7 @@ use sp_consensus_grandpa::{
AuthorityList, AuthoritySignature, SetId, CLIENT_LOG_TARGET as LOG_TARGET,
};
use sp_core::{crypto::ByteArray, traits::CallContext};
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, NumberFor, Zero},
@@ -1141,7 +1141,7 @@ fn local_authority_id(
keystore.and_then(|keystore| {
voters
.iter()
.find(|(p, _)| Keystore::has_keys(&**keystore, &[(p.to_raw_vec(), AuthorityId::ID)]))
.find(|(p, _)| keystore.has_keys(&[(p.to_raw_vec(), AuthorityId::ID)]))
.map(|(p, _)| p.clone())
})
}
@@ -281,10 +281,11 @@ fn make_ids(keys: &[Ed25519Keyring]) -> AuthorityList {
}
fn create_keystore(authority: Ed25519Keyring) -> KeystorePtr {
let keystore = Arc::new(MemoryKeystore::new());
Keystore::ed25519_generate_new(&*keystore, GRANDPA, Some(&authority.to_seed()))
.expect("Creates authority key");
let keystore = MemoryKeystore::new();
keystore
.ed25519_generate_new(GRANDPA, Some(&authority.to_seed()))
.expect("Creates authority key");
keystore.into()
}
async fn run_until_complete(future: impl Future + Unpin, net: &Arc<Mutex<GrandpaTestNet>>) {
+24 -19
View File
@@ -135,6 +135,9 @@ impl Keystore for LocalKeystore {
.unwrap_or_default()
}
/// Generate a new pair compatible with the 'ed25519' signature scheme.
///
/// If the `[seed]` is `Some` then the key will be ephemeral and stored in memory.
fn sr25519_generate_new(
&self,
id: KeyTypeId,
@@ -162,6 +165,9 @@ impl Keystore for LocalKeystore {
.unwrap_or_default()
}
/// Generate a new pair compatible with the 'sr25519' signature scheme.
///
/// If the `[seed]` is `Some` then the key will be ephemeral and stored in memory.
fn ed25519_generate_new(
&self,
id: KeyTypeId,
@@ -189,6 +195,9 @@ impl Keystore for LocalKeystore {
.unwrap_or_default()
}
/// Generate a new pair compatible with the 'ecdsa' signature scheme.
///
/// If the `[seed]` is `Some` then the key will be ephemeral and stored in memory.
fn ecdsa_generate_new(
&self,
id: KeyTypeId,
@@ -504,17 +513,14 @@ mod tests {
let key: ed25519::AppPair = store.0.write().generate().unwrap();
let key2 = ed25519::Pair::generate().0;
assert!(!Keystore::has_keys(&store, &[(key2.public().to_vec(), ed25519::AppPublic::ID)]));
assert!(!store.has_keys(&[(key2.public().to_vec(), ed25519::AppPublic::ID)]));
assert!(!Keystore::has_keys(
&store,
&[
(key2.public().to_vec(), ed25519::AppPublic::ID),
(key.public().to_raw_vec(), ed25519::AppPublic::ID),
],
));
assert!(!store.has_keys(&[
(key2.public().to_vec(), ed25519::AppPublic::ID),
(key.public().to_raw_vec(), ed25519::AppPublic::ID),
],));
assert!(Keystore::has_keys(&store, &[(key.public().to_raw_vec(), ed25519::AppPublic::ID)]));
assert!(store.has_keys(&[(key.public().to_raw_vec(), ed25519::AppPublic::ID)]));
}
#[test]
@@ -626,31 +632,30 @@ mod tests {
let file_name = temp_dir.path().join(array_bytes::bytes2hex("", &SR25519.0[..2]));
fs::write(file_name, "test").expect("Invalid file is written");
assert!(Keystore::sr25519_public_keys(&store, SR25519).is_empty());
assert!(store.sr25519_public_keys(SR25519).is_empty());
}
#[test]
fn generate_with_seed_is_not_stored() {
let temp_dir = TempDir::new().unwrap();
let store = LocalKeystore::open(temp_dir.path(), None).unwrap();
let _alice_tmp_key =
Keystore::sr25519_generate_new(&store, TEST_KEY_TYPE, Some("//Alice")).unwrap();
let _alice_tmp_key = store.sr25519_generate_new(TEST_KEY_TYPE, Some("//Alice")).unwrap();
assert_eq!(Keystore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 1);
assert_eq!(store.sr25519_public_keys(TEST_KEY_TYPE).len(), 1);
drop(store);
let store = LocalKeystore::open(temp_dir.path(), None).unwrap();
assert_eq!(Keystore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 0);
assert_eq!(store.sr25519_public_keys(TEST_KEY_TYPE).len(), 0);
}
#[test]
fn generate_can_be_fetched_in_memory() {
let store = LocalKeystore::in_memory();
Keystore::sr25519_generate_new(&store, TEST_KEY_TYPE, Some("//Alice")).unwrap();
store.sr25519_generate_new(TEST_KEY_TYPE, Some("//Alice")).unwrap();
assert_eq!(Keystore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 1);
Keystore::sr25519_generate_new(&store, TEST_KEY_TYPE, None).unwrap();
assert_eq!(Keystore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 2);
assert_eq!(store.sr25519_public_keys(TEST_KEY_TYPE).len(), 1);
store.sr25519_generate_new(TEST_KEY_TYPE, None).unwrap();
assert_eq!(store.sr25519_public_keys(TEST_KEY_TYPE).len(), 2);
}
#[test]
@@ -661,7 +666,7 @@ mod tests {
let temp_dir = TempDir::new().unwrap();
let store = LocalKeystore::open(temp_dir.path(), None).unwrap();
let public = Keystore::sr25519_generate_new(&store, TEST_KEY_TYPE, None).unwrap();
let public = store.sr25519_generate_new(TEST_KEY_TYPE, None).unwrap();
let path = store.0.read().key_file_path(public.as_ref(), TEST_KEY_TYPE).unwrap();
let permissions = File::open(path).unwrap().metadata().unwrap().permissions();
+5 -4
View File
@@ -40,7 +40,7 @@ use sc_transaction_pool_api::{
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_core::Bytes;
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use sp_runtime::{generic, traits::Block as BlockT};
use sp_session::SessionKeys;
@@ -112,7 +112,8 @@ where
self.deny_unsafe.check_if_safe()?;
let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?;
Keystore::insert(&*self.keystore, key_type, &suri, &public[..])
self.keystore
.insert(key_type, &suri, &public[..])
.map_err(|_| Error::KeystoreUnavailable)?;
Ok(())
}
@@ -139,14 +140,14 @@ where
.map_err(|e| Error::Client(Box::new(e)))?
.ok_or(Error::InvalidSessionKeys)?;
Ok(Keystore::has_keys(&*self.keystore, &keys))
Ok(self.keystore.has_keys(&keys))
}
fn has_key(&self, public_key: Bytes, key_type: String) -> RpcResult<bool> {
self.deny_unsafe.check_if_safe()?;
let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?;
Ok(Keystore::has_keys(&*self.keystore, &[(public_key.to_vec(), key_type)]))
Ok(self.keystore.has_keys(&[(public_key.to_vec(), key_type)]))
}
fn pending_extrinsics(&self) -> RpcResult<Vec<Bytes>> {
+4 -4
View File
@@ -36,7 +36,7 @@ use sp_core::{
testing::{ED25519, SR25519},
H256,
};
use sp_keystore::testing::MemoryKeystore;
use sp_keystore::{testing::MemoryKeystore, Keystore};
use std::sync::Arc;
use substrate_test_runtime_client::{
self,
@@ -225,7 +225,7 @@ async fn author_should_insert_key() {
keypair.public().0.to_vec().into(),
);
api.call::<_, ()>("author_insertKey", params).await.unwrap();
let pubkeys = Keystore::keys(&*setup.keystore, ED25519).unwrap();
let pubkeys = setup.keystore.keys(ED25519).unwrap();
assert!(
pubkeys.contains(&CryptoTypePublicPair(ed25519::CRYPTO_ID, keypair.public().to_raw_vec()))
@@ -240,8 +240,8 @@ async fn author_should_rotate_keys() {
let new_pubkeys: Bytes = api.call("author_rotateKeys", EmptyParams::new()).await.unwrap();
let session_keys =
SessionKeys::decode(&mut &new_pubkeys[..]).expect("SessionKeys decode successfully");
let ed25519_pubkeys = Keystore::keys(&*setup.keystore, ED25519).unwrap();
let sr25519_pubkeys = Keystore::keys(&*setup.keystore, SR25519).unwrap();
let ed25519_pubkeys = setup.keystore.keys(ED25519).unwrap();
let sr25519_pubkeys = setup.keystore.keys(SR25519).unwrap();
assert!(ed25519_pubkeys
.contains(&CryptoTypePublicPair(ed25519::CRYPTO_ID, session_keys.ed25519.to_raw_vec())));
assert!(sr25519_pubkeys
+10 -50
View File
@@ -67,7 +67,7 @@ use sp_consensus::block_validation::{
BlockAnnounceValidator, Chain, DefaultBlockAnnounceValidator,
};
use sp_core::traits::{CodeExecutor, SpawnNamed};
use sp_keystore::{Keystore, KeystorePtr};
use sp_keystore::KeystorePtr;
use sp_runtime::traits::{Block as BlockT, BlockIdTo, NumberFor, Zero};
use std::{str::FromStr, sync::Arc, time::SystemTime};
@@ -85,24 +85,8 @@ pub type TFullCallExecutor<TBl, TExec> =
type TFullParts<TBl, TRtApi, TExec> =
(TFullClient<TBl, TRtApi, TExec>, Arc<TFullBackend<TBl>>, KeystoreContainer, TaskManager);
trait AsKeystoreRef {
fn keystore_ref(&self) -> Arc<dyn Keystore>;
}
impl<T> AsKeystoreRef for Arc<T>
where
T: Keystore + 'static,
{
fn keystore_ref(&self) -> Arc<dyn Keystore> {
self.clone()
}
}
/// Construct and hold different layers of Keystore wrappers
pub struct KeystoreContainer {
remote: Option<Box<dyn AsKeystoreRef>>,
local: Arc<LocalKeystore>,
}
/// Construct a local keystore shareable container
pub struct KeystoreContainer(Arc<LocalKeystore>);
impl KeystoreContainer {
/// Construct KeystoreContainer
@@ -113,41 +97,17 @@ impl KeystoreContainer {
KeystoreConfig::InMemory => LocalKeystore::in_memory(),
});
Ok(Self { remote: Default::default(), local: keystore })
Ok(Self(keystore))
}
/// Set the remote keystore.
/// Should be called right away at startup and not at runtime:
/// even though this overrides any previously set remote store, it
/// does not reset any references previously handed out - they will
/// stick around.
pub fn set_remote_keystore<T>(&mut self, remote: Arc<T>)
where
T: Keystore + 'static,
{
self.remote = Some(Box::new(remote))
/// Returns a shared reference to a dynamic `Keystore` trait implementation.
pub fn keystore(&self) -> KeystorePtr {
self.0.clone()
}
/// Returns an adapter to a `Keystore` implementation.
pub fn keystore(&self) -> Arc<dyn Keystore> {
if let Some(c) = self.remote.as_ref() {
c.keystore_ref()
} else {
self.local.clone()
}
}
/// Returns the local keystore if available
///
/// The function will return None if the available keystore is not a local keystore.
///
/// # Note
///
/// Using the [`LocalKeystore`] will result in loosing the ability to use any other keystore
/// implementation, like a remote keystore for example. Only use this if you a certain that you
/// require it!
pub fn local_keystore(&self) -> Option<Arc<LocalKeystore>> {
Some(self.local.clone())
/// Returns a shared reference to the local keystore .
pub fn local_keystore(&self) -> Arc<LocalKeystore> {
self.0.clone()
}
}
-2
View File
@@ -61,8 +61,6 @@ pub struct Configuration {
pub network: NetworkConfiguration,
/// Configuration for the keystore.
pub keystore: KeystoreConfig,
/// Remote URI to connect to for async keystore support
pub keystore_remote: Option<String>,
/// Configuration for the database.
pub database: DatabaseSource,
/// Maximum size of internal trie cache in bytes.
-1
View File
@@ -242,7 +242,6 @@ fn node_config<
tokio_handle,
transaction_pool: Default::default(),
network: network_config,
keystore_remote: Default::default(),
keystore: KeystoreConfig::Path { path: root.join("key"), password: None },
database: DatabaseSource::RocksDb { path: root.join("db"), cache_size: 128 },
trie_cache_maximum_size: Some(16 * 1024 * 1024),