mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 16:01:04 +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:
@@ -30,8 +30,10 @@ use substrate_bip39::mini_secret_from_entropy;
|
||||
#[cfg(feature = "std")]
|
||||
use bip39::{Mnemonic, Language, MnemonicType};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::crypto::{Pair as TraitPair, DeriveJunction, Infallible, SecretStringError, Derive, Ss58Codec};
|
||||
use crate::crypto::{key_types, KeyTypeId, Public as TraitPublic, TypedKey, UncheckedFrom};
|
||||
use crate::crypto::{
|
||||
Pair as TraitPair, DeriveJunction, Infallible, SecretStringError, Ss58Codec
|
||||
};
|
||||
use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}};
|
||||
use crate::hash::{H256, H512};
|
||||
use codec::{Encode, Decode};
|
||||
|
||||
@@ -56,19 +58,13 @@ pub struct Pair(Keypair);
|
||||
impl Clone for Pair {
|
||||
fn clone(&self) -> Self {
|
||||
Pair(schnorrkel::Keypair {
|
||||
public: self.0.public.clone(),
|
||||
public: self.0.public,
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8; 32]> for Public {
|
||||
fn as_ref(&self) -> &[u8; 32] {
|
||||
&self.0
|
||||
@@ -99,6 +95,20 @@ impl From<Public> for H256 {
|
||||
}
|
||||
}
|
||||
|
||||
impl rstd::convert::TryFrom<&[u8]> for Public {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
|
||||
if data.len() == 32 {
|
||||
let mut inner = [0u8; 32];
|
||||
inner.copy_from_slice(data);
|
||||
Ok(Public(inner))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UncheckedFrom<[u8; 32]> for Public {
|
||||
fn unchecked_from(x: [u8; 32]) -> Self {
|
||||
Public::from_raw(x)
|
||||
@@ -112,15 +122,15 @@ impl UncheckedFrom<H256> for Public {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl ::std::fmt::Display for Public {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
impl std::fmt::Display for Public {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self.to_ss58check())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl ::std::fmt::Debug for Public {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
impl std::fmt::Debug for Public {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
let s = self.to_ss58check();
|
||||
write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8])
|
||||
}
|
||||
@@ -142,8 +152,8 @@ impl<'de> Deserialize<'de> for Public {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl ::std::hash::Hash for Public {
|
||||
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
|
||||
impl std::hash::Hash for Public {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
}
|
||||
@@ -154,6 +164,20 @@ impl ::std::hash::Hash for Public {
|
||||
#[derive(Encode, Decode)]
|
||||
pub struct Signature(pub [u8; 64]);
|
||||
|
||||
impl rstd::convert::TryFrom<&[u8]> for Signature {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
|
||||
if data.len() == 64 {
|
||||
let mut inner = [0u8; 64];
|
||||
inner.copy_from_slice(data);
|
||||
Ok(Signature(inner))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Signature {
|
||||
fn clone(&self) -> Self {
|
||||
let mut r = [0u8; 64];
|
||||
@@ -170,7 +194,7 @@ impl Default for Signature {
|
||||
|
||||
impl PartialEq for Signature {
|
||||
fn eq(&self, b: &Self) -> bool {
|
||||
&self.0[..] == &b.0[..]
|
||||
self.0[..] == b.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,11 +292,11 @@ impl Signature {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Derive for Public {
|
||||
/// Derive a child key from a series of given junctions.
|
||||
///
|
||||
/// `None` if there are any hard junctions in there.
|
||||
#[cfg(feature = "std")]
|
||||
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self, path: Iter) -> Option<Public> {
|
||||
let mut acc = PublicKey::from_bytes(self.as_ref()).ok()?;
|
||||
for j in path {
|
||||
@@ -318,24 +342,6 @@ impl TraitPublic for Public {
|
||||
r.copy_from_slice(data);
|
||||
Public(r)
|
||||
}
|
||||
|
||||
/// Return a `Vec<u8>` filled with raw data.
|
||||
#[cfg(feature = "std")]
|
||||
fn to_raw_vec(&self) -> Vec<u8> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
|
||||
/// Return a slice filled with raw data.
|
||||
fn as_slice(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl AsRef<Pair> for Pair {
|
||||
fn as_ref(&self) -> &Pair {
|
||||
&self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -475,20 +481,15 @@ impl TraitPair for Pair {
|
||||
}
|
||||
|
||||
/// Verify a signature on a message. Returns true if the signature is good.
|
||||
fn verify<P: AsRef<Self::Public>, M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: P) -> bool {
|
||||
// Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets
|
||||
// that have not been upgraded and those that have. To swap to 0.8.0 only,
|
||||
// create `schnorrkel::Signature` and pass that into `verify_simple`
|
||||
match PublicKey::from_bytes(pubkey.as_ref().as_slice()) {
|
||||
Ok(pk) => pk.verify_simple_preaudit_deprecated(
|
||||
SIGNING_CTX, message.as_ref(), &sig.as_ref(),
|
||||
).is_ok(),
|
||||
Err(_) => false,
|
||||
}
|
||||
fn verify<M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool {
|
||||
Self::verify_weak(&sig.0[..], message, pubkey)
|
||||
}
|
||||
|
||||
/// Verify a signature on a message. Returns true if the signature is good.
|
||||
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool {
|
||||
// Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets
|
||||
// that have not been upgraded and those that have. To swap to 0.8.0 only,
|
||||
// create `schnorrkel::Signature` and pass that into `verify_simple`
|
||||
match PublicKey::from_bytes(pubkey.as_ref()) {
|
||||
Ok(pk) => pk.verify_simple_preaudit_deprecated(
|
||||
SIGNING_CTX, message.as_ref(), &sig,
|
||||
@@ -518,17 +519,19 @@ impl Pair {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypedKey for Public {
|
||||
const KEY_TYPE: KeyTypeId = key_types::SR25519;
|
||||
impl CryptoType for Public {
|
||||
#[cfg(feature="std")]
|
||||
type Pair = Pair;
|
||||
}
|
||||
|
||||
impl TypedKey for Signature {
|
||||
const KEY_TYPE: KeyTypeId = key_types::SR25519;
|
||||
impl CryptoType for Signature {
|
||||
#[cfg(feature="std")]
|
||||
type Pair = Pair;
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl TypedKey for Pair {
|
||||
const KEY_TYPE: KeyTypeId = key_types::SR25519;
|
||||
impl CryptoType for Pair {
|
||||
type Pair = Pair;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -713,6 +716,6 @@ mod test {
|
||||
let js_signature = Signature::from_raw(hex!(
|
||||
"28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00"
|
||||
));
|
||||
assert!(Pair::verify(&js_signature, b"SUBSTRATE", public));
|
||||
assert!(Pair::verify(&js_signature, b"SUBSTRATE", &public));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user