-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Keystore overhaul (final) #13683
Keystore overhaul (final) #13683
Conversation
Untyped generics are accessible using associated types 'Generic' associated type. I.e. <T as AppKey>::Public::Generic
bot merge |
use codec::Encode; | ||
|
||
let signature = match crypto_id { | ||
sr25519::CRYPTO_ID => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you wanted to remove CRYPTO_ID
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was indeed the awesome original idea.
Unfortunately, though, considering that AURA is generic over the crypto scheme, we need a way to select the correct scheme to use.
The ideal solution (IIRC something like what you suggested during our chat), is to have a sign-with method generic over an object implementing Pair
.
That is, something like this
Thus a generic sign_with
method would look like:
fn sign_with<P: Pair>(&self, id: AppCryptoId, public: &P::Public, msg: &[u8]) -> P::Signature;
Sadly a trait with a method like this can't be made into a trait-objejct (as it depends on a generic type) and we use the keystore as a Arc<dyn Keystore>
all over the project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly a trait with a method like this can't be made into a trait-objejct (as it depends on a generic type) and we use the keystore as a
Arc<dyn Keystore>
all over the project.
Well, if you'd go through &dyn
then you could, e.g.:
use std::sync::Arc;
trait Public {}
trait Pair {
type Public: Public;
type Signature: 'static;
}
trait Keystore {
fn yo_sign_this_plz_impl(&self, pair: &dyn Public) -> Box<dyn std::any::Any>;
}
impl dyn Keystore {
fn yo_sign_this_plz<P: Pair>(&self, pair: &P::Public) -> P::Signature {
match self.yo_sign_this_plz_impl(pair).downcast() {
Ok(sig) => *sig,
Err(_) => unreachable!()
}
}
}
fn it_works<P: Pair>(keystore: Arc<dyn Keystore>, pubkey: P::Public) -> P::Signature {
keystore.yo_sign_this_plz::<P>(&pubkey)
}
But (in this example) this would require that Public
is now object safe, so you'd have to use similar tricks for it, and so on until you make everything object safe all the way to the bottom. It's turtles all the way down. Probably not worth it though?
* Introduce keystore specialized sign methods * Get rid of 'AppKey::UntypedGeneric' associated type. Untyped generics are accessible using associated types 'Generic' associated type. I.e. <T as AppKey>::Public::Generic * Get rid of 'CryptoTypePublicPair' * Trivial fix * Small refactory of local keystore implementations * Remove 'crypto_id' method from 'Public' * Trivial rename of 'AppKey' to 'AppCrypto' * Remove unused import * Improve docs * Better signature related errors for authority-discovery * Apply review suggestion * Apply review suggestions Co-authored-by: Koute <[email protected]> * Authority discoverty signing error revisited * Signing error revisited for babe and aura as well * Further cleanup --------- Co-authored-by: Koute <[email protected]>
* Introduce keystore specialized sign methods * Get rid of 'AppKey::UntypedGeneric' associated type. Untyped generics are accessible using associated types 'Generic' associated type. I.e. <T as AppKey>::Public::Generic * Get rid of 'CryptoTypePublicPair' * Trivial fix * Small refactory of local keystore implementations * Remove 'crypto_id' method from 'Public' * Trivial rename of 'AppKey' to 'AppCrypto' * Remove unused import * Improve docs * Better signature related errors for authority-discovery * Apply review suggestion * Apply review suggestions Co-authored-by: Koute <[email protected]> * Authority discoverty signing error revisited * Signing error revisited for babe and aura as well * Further cleanup --------- Co-authored-by: Koute <[email protected]>
Closes #13556
polkadot companion: paritytech/polkadot#6944
cumulus companion: paritytech/cumulus#2371
Within this PR:
CryptoTypePublicId
typeKeystore
traitKeystore::sign_with
method has been retained. But a default implementation has been provided in the trait definition. In the end this is a convenience method that can be used in some specific use cases (to prevent code duplication in all the cases where the key is generic such as AURA).AppKey
trait toAppCrypto
. The trait is implemented by types (signatures included) from whom the whole set of application crypto associated types and consts can be retrieved. Thus this new name fits betterCRYPTO_ID
inAppCrypto
has been retained because without itsign_with
can't worksign_with