mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 00:51:06 +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:
@@ -16,11 +16,12 @@
|
||||
|
||||
//! Offchain workers types
|
||||
|
||||
use crate::crypto;
|
||||
use codec::{Encode, Decode};
|
||||
use rstd::prelude::{Vec, Box};
|
||||
use rstd::convert::TryFrom;
|
||||
|
||||
pub use crate::crypto::KeyTypeId;
|
||||
|
||||
/// A type of supported crypto.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
@@ -58,81 +59,6 @@ impl From<StorageKind> for u32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type of supported crypto.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
#[repr(C)]
|
||||
pub enum CryptoKind {
|
||||
/// SR25519 crypto (Schnorrkel)
|
||||
Sr25519 = crypto::key_types::SR25519 as isize,
|
||||
/// ED25519 crypto (Edwards)
|
||||
Ed25519 = crypto::key_types::ED25519 as isize,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for CryptoKind {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(kind: u32) -> Result<Self, Self::Error> {
|
||||
match kind {
|
||||
e if e == CryptoKind::Sr25519 as isize as u32 => Ok(CryptoKind::Sr25519),
|
||||
e if e == CryptoKind::Ed25519 as isize as u32 => Ok(CryptoKind::Ed25519),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CryptoKind> for u32 {
|
||||
fn from(c: CryptoKind) -> Self {
|
||||
c as isize as u32
|
||||
}
|
||||
}
|
||||
|
||||
/// Key to use in the offchain worker crypto api.
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum CryptoKey {
|
||||
/// Use a key from the offchain workers local storage.
|
||||
LocalKey {
|
||||
/// The id of the key.
|
||||
id: u16,
|
||||
/// The kind of the key.
|
||||
kind: CryptoKind,
|
||||
},
|
||||
/// Use the key the block authoring algorithm uses.
|
||||
AuthorityKey,
|
||||
/// Use the key the finality gadget uses.
|
||||
FgAuthorityKey,
|
||||
}
|
||||
|
||||
impl TryFrom<u64> for CryptoKey {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(key: u64) -> Result<Self, Self::Error> {
|
||||
match key & 0xFF {
|
||||
0 => {
|
||||
let id = (key >> 8 & 0xFFFF) as u16;
|
||||
let kind = CryptoKind::try_from((key >> 32) as u32)?;
|
||||
Ok(CryptoKey::LocalKey { id, kind })
|
||||
}
|
||||
1 => Ok(CryptoKey::AuthorityKey),
|
||||
2 => Ok(CryptoKey::FgAuthorityKey),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CryptoKey> for u64 {
|
||||
fn from(key: CryptoKey) -> u64 {
|
||||
match key {
|
||||
CryptoKey::LocalKey { id, kind } => {
|
||||
((kind as u64) << 32) | ((id as u64) << 8)
|
||||
}
|
||||
CryptoKey::AuthorityKey => 1,
|
||||
CryptoKey::FgAuthorityKey => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Opaque type for offchain http requests.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
@@ -314,45 +240,6 @@ pub trait Externalities {
|
||||
/// Returns information about the local node's network state.
|
||||
fn network_state(&self) -> Result<OpaqueNetworkState, ()>;
|
||||
|
||||
/// Create new key(pair) for signing/encryption/decryption.
|
||||
///
|
||||
/// Returns an error if given crypto kind is not supported.
|
||||
fn new_crypto_key(&mut self, crypto: CryptoKind) -> Result<CryptoKey, ()>;
|
||||
|
||||
/// Returns the locally configured authority public key, if available.
|
||||
fn pubkey(&self, key: CryptoKey) -> Result<Vec<u8>, ()>;
|
||||
|
||||
/// Encrypt a piece of data using given crypto key.
|
||||
///
|
||||
/// If `key` is `None`, it will attempt to use current authority key of `CryptoKind`.
|
||||
///
|
||||
/// Returns an error if `key` is not available or does not exist,
|
||||
/// or the expected `CryptoKind` does not match.
|
||||
fn encrypt(&mut self, key: CryptoKey, data: &[u8]) -> Result<Vec<u8>, ()>;
|
||||
|
||||
/// Decrypt a piece of data using given crypto key.
|
||||
///
|
||||
/// If `key` is `None`, it will attempt to use current authority key of `CryptoKind`.
|
||||
///
|
||||
/// Returns an error if data cannot be decrypted or the `key` is not available or does not exist,
|
||||
/// or the expected `CryptoKind` does not match.
|
||||
fn decrypt(&mut self, key: CryptoKey, data: &[u8]) -> Result<Vec<u8>, ()>;
|
||||
|
||||
/// Sign a piece of data using given crypto key.
|
||||
///
|
||||
/// If `key` is `None`, it will attempt to use current authority key of `CryptoKind`.
|
||||
///
|
||||
/// Returns an error if `key` is not available or does not exist,
|
||||
/// or the expected `CryptoKind` does not match.
|
||||
fn sign(&mut self, key: CryptoKey, data: &[u8]) -> Result<Vec<u8>, ()>;
|
||||
|
||||
/// Verifies that `signature` for `msg` matches given `key`.
|
||||
///
|
||||
/// Returns an `Ok` with `true` in case it does, `false` in case it doesn't.
|
||||
/// Returns an error in case the key is not available or does not exist or the parameters
|
||||
/// lengths are incorrect or `CryptoKind` does not match.
|
||||
fn verify(&mut self, key: CryptoKey, msg: &[u8], signature: &[u8]) -> Result<bool, ()>;
|
||||
|
||||
/// Returns current UNIX timestamp (in millis)
|
||||
fn timestamp(&mut self) -> Timestamp;
|
||||
|
||||
@@ -466,34 +353,10 @@ impl<T: Externalities + ?Sized> Externalities for Box<T> {
|
||||
(&mut **self).submit_transaction(ex)
|
||||
}
|
||||
|
||||
fn new_crypto_key(&mut self, crypto: CryptoKind) -> Result<CryptoKey, ()> {
|
||||
(&mut **self).new_crypto_key(crypto)
|
||||
}
|
||||
|
||||
fn encrypt(&mut self, key: CryptoKey, data: &[u8]) -> Result<Vec<u8>, ()> {
|
||||
(&mut **self).encrypt(key, data)
|
||||
}
|
||||
|
||||
fn network_state(&self) -> Result<OpaqueNetworkState, ()> {
|
||||
(& **self).network_state()
|
||||
}
|
||||
|
||||
fn pubkey(&self, key: CryptoKey) -> Result<Vec<u8>, ()> {
|
||||
(&**self).pubkey(key)
|
||||
}
|
||||
|
||||
fn decrypt(&mut self, key: CryptoKey, data: &[u8]) -> Result<Vec<u8>, ()> {
|
||||
(&mut **self).decrypt(key, data)
|
||||
}
|
||||
|
||||
fn sign(&mut self, key: CryptoKey, data: &[u8]) -> Result<Vec<u8>, ()> {
|
||||
(&mut **self).sign(key, data)
|
||||
}
|
||||
|
||||
fn verify(&mut self, key: CryptoKey, msg: &[u8], signature: &[u8]) -> Result<bool, ()> {
|
||||
(&mut **self).verify(key, msg, signature)
|
||||
}
|
||||
|
||||
fn timestamp(&mut self) -> Timestamp {
|
||||
(&mut **self).timestamp()
|
||||
}
|
||||
@@ -571,27 +434,4 @@ mod tests {
|
||||
assert_eq!(t.sub(Duration::from_millis(10)), Timestamp(0));
|
||||
assert_eq!(t.diff(&Timestamp(3)), Duration(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crypto_key_to_from_u64() {
|
||||
let key = CryptoKey::AuthorityKey;
|
||||
let uint: u64 = key.clone().into();
|
||||
let key2 = CryptoKey::try_from(uint).unwrap();
|
||||
assert_eq!(key, key2);
|
||||
|
||||
let key = CryptoKey::FgAuthorityKey;
|
||||
let uint: u64 = key.clone().into();
|
||||
let key2 = CryptoKey::try_from(uint).unwrap();
|
||||
assert_eq!(key, key2);
|
||||
|
||||
let key = CryptoKey::LocalKey { id: 0, kind: CryptoKind::Ed25519 };
|
||||
let uint: u64 = key.clone().into();
|
||||
let key2 = CryptoKey::try_from(uint).unwrap();
|
||||
assert_eq!(key, key2);
|
||||
|
||||
let key = CryptoKey::LocalKey { id: 10, kind: CryptoKind::Sr25519 };
|
||||
let uint: u64 = key.clone().into();
|
||||
let key2 = CryptoKey::try_from(uint).unwrap();
|
||||
assert_eq!(key, key2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user