Generic keystore (#3008)

* Add KeyTypeId.

* Implement clone for sr25519::Pair.

* Extend Pair with to_raw_vec.

* Implement TypedKey for Signature and Pair.

* Add trait Public.

* Make keystore generic.

* Fixup clone.

* Fix tests.

* Update service.

* Fix imports.

* Fix build.

* Fix babe build.

* Fix subkey build.

* Make authority setup generic.

* Update node-template.

* Fix build.

* Remove unsafe code.

* Fix tests.
This commit is contained in:
David Craven
2019-07-04 13:14:55 +02:00
committed by GitHub
parent 336053f7ae
commit 51e345c901
15 changed files with 279 additions and 122 deletions
+67 -27
View File
@@ -31,13 +31,14 @@ use substrate_bip39::mini_secret_from_entropy;
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "std")]
use crate::crypto::{Pair as TraitPair, DeriveJunction, Infallible, SecretStringError, Derive, Ss58Codec};
use crate::{hash::{H256, H512}, crypto::UncheckedFrom};
use crate::crypto::{key_types, KeyTypeId, Public as TraitPublic, TypedKey, UncheckedFrom};
use crate::hash::{H256, H512};
use parity_codec::{Encode, Decode};
#[cfg(feature = "std")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "std")]
use schnorrkel::keys::MINI_SECRET_KEY_LENGTH;
use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH};
// signing context
#[cfg(feature = "std")]
@@ -51,6 +52,17 @@ pub struct Public(pub [u8; 32]);
#[cfg(feature = "std")]
pub struct Pair(Keypair);
#[cfg(feature = "std")]
impl Clone for Pair {
fn clone(&self) -> Self {
Pair(schnorrkel::Keypair {
public: self.0.public.clone(),
secret: schnorrkel::SecretKey::from_bytes(&self.0.secret.to_bytes()[..])
.expect("key is always the correct size; qed")
})
}
}
impl AsRef<Public> for Public {
fn as_ref(&self) -> &Public {
&self
@@ -282,16 +294,6 @@ impl Public {
Public(data)
}
/// A new instance from the given slice that should be 32 bytes long.
///
/// NOTE: No checking goes on to ensure this is a real public key. Only use it if
/// you are certain that the array actually is a pubkey. GIGO!
pub fn from_slice(data: &[u8]) -> Self {
let mut r = [0u8; 32];
r.copy_from_slice(data);
Public(r)
}
/// A new instance from an H256.
///
/// NOTE: No checking goes on to ensure this is a real public key. Only use it if
@@ -300,21 +302,33 @@ impl Public {
Public(x.into())
}
/// Return a slice filled with raw data.
pub fn as_array_ref(&self) -> &[u8; 32] {
self.as_ref()
}
}
impl TraitPublic for Public {
/// A new instance from the given slice that should be 32 bytes long.
///
/// NOTE: No checking goes on to ensure this is a real public key. Only use it if
/// you are certain that the array actually is a pubkey. GIGO!
fn from_slice(data: &[u8]) -> Self {
let mut r = [0u8; 32];
r.copy_from_slice(data);
Public(r)
}
/// Return a `Vec<u8>` filled with raw data.
#[cfg(feature = "std")]
pub fn into_raw_vec(self) -> Vec<u8> {
fn to_raw_vec(&self) -> Vec<u8> {
self.0.to_vec()
}
/// Return a slice filled with raw data.
pub fn as_slice(&self) -> &[u8] {
fn as_slice(&self) -> &[u8] {
&self.0
}
/// Return a slice filled with raw data.
pub fn as_array_ref(&self) -> &[u8; 32] {
self.as_ref()
}
}
#[cfg(feature = "std")]
@@ -397,14 +411,22 @@ impl TraitPair for Pair {
///
/// You should never need to use this; generate(), generate_with_phrase(), from_phrase()
fn from_seed_slice(seed: &[u8]) -> Result<Pair, SecretStringError> {
if seed.len() != MINI_SECRET_KEY_LENGTH {
Err(SecretStringError::InvalidSeedLength)
} else {
Ok(Pair(
MiniSecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.expand_to_keypair()
))
match seed.len() {
MINI_SECRET_KEY_LENGTH => {
Ok(Pair(
MiniSecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.expand_to_keypair()
))
}
SECRET_KEY_LENGTH => {
Ok(Pair(
SecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.to_keypair()
))
}
_ => Err(SecretStringError::InvalidSeedLength)
}
}
@@ -478,6 +500,11 @@ impl TraitPair for Pair {
Err(_) => false,
}
}
/// Return a vec filled with raw data.
fn to_raw_vec(&self) -> Vec<u8> {
self.0.secret.to_bytes().to_vec()
}
}
#[cfg(feature = "std")]
@@ -495,6 +522,19 @@ impl Pair {
}
}
impl TypedKey for Public {
const KEY_TYPE: KeyTypeId = key_types::SR25519;
}
impl TypedKey for Signature {
const KEY_TYPE: KeyTypeId = key_types::SR25519;
}
#[cfg(feature = "std")]
impl TypedKey for Pair {
const KEY_TYPE: KeyTypeId = key_types::SR25519;
}
#[cfg(test)]
mod test {
use super::*;