mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
Add abstraction for the embedded elliptic curve keys
It's minimal but still pleasant.
This commit is contained in:
@@ -21,22 +21,22 @@ bitvec = { version = "1", default-features = false, features = ["alloc", "serde"
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "bit-vec"] }
|
||||
scale-info = { version = "2", default-features = false, features = ["derive", "bit-vec"] }
|
||||
|
||||
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
|
||||
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
|
||||
serai-primitives = { path = "../primitives", default-features = false, features = ["non_canonical_scale_derivations"] }
|
||||
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
#pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
#pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
|
||||
#sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "74839cba4a7f48023080215e5194fd6ab7e270e5", default-features = false }
|
||||
#sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ece373ca1e8aaee67844eebcca28b5e016136dba", default-features = false }
|
||||
|
||||
#ciphersuite = { path = "../../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||
#dalek-ff-group = { path = "../../../crypto/dalek-ff-group", default-features = false, features = ["std"] }
|
||||
|
||||
53
substrate/validator-sets/src/embedded_elliptic_curve_keys.rs
Normal file
53
substrate/validator-sets/src/embedded_elliptic_curve_keys.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use sp_core::{Encode, sr25519::Public};
|
||||
|
||||
use serai_primitives::{crypto::SignedEmbeddedEllipticCurveKeys, network_id::*};
|
||||
|
||||
use frame_support::storage::StorageDoubleMap;
|
||||
|
||||
pub(crate) trait EmbeddedEllipticCurveKeysStorage {
|
||||
/// An opaque map storing keys on an embedded elliptic curve.
|
||||
type EmbeddedEllipticCurveKeys: StorageDoubleMap<
|
||||
ExternalNetworkId,
|
||||
Public,
|
||||
serai_primitives::crypto::EmbeddedEllipticCurveKeys,
|
||||
Query = Option<serai_primitives::crypto::EmbeddedEllipticCurveKeys>,
|
||||
>;
|
||||
}
|
||||
|
||||
/// An interface for managing validators' embedded elliptic curve keys.
|
||||
pub(crate) trait EmbeddedEllipticCurveKeys {
|
||||
/// Set a validator's embedded elliptic curve keys for an external network.
|
||||
fn set_embedded_elliptic_curve_keys(
|
||||
validator: Public,
|
||||
keys: SignedEmbeddedEllipticCurveKeys,
|
||||
) -> Result<(), ()>;
|
||||
/// Check if a validator still needs to set embedded elliptic curve keys.
|
||||
fn still_needs_to_set_embedded_elliptic_curve_keys(network: NetworkId, validator: Public)
|
||||
-> bool;
|
||||
}
|
||||
|
||||
impl<S: EmbeddedEllipticCurveKeysStorage> EmbeddedEllipticCurveKeys for S {
|
||||
/// Set a validator's embedded elliptic curve keys, for an external network.
|
||||
fn set_embedded_elliptic_curve_keys(
|
||||
validator: Public,
|
||||
keys: SignedEmbeddedEllipticCurveKeys,
|
||||
) -> Result<(), ()> {
|
||||
let keys = keys.verify(validator.into()).ok_or(())?;
|
||||
S::EmbeddedEllipticCurveKeys::set(keys.network(), validator, Some(keys));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if a validator still needs to set embedded elliptic curve keys.
|
||||
fn still_needs_to_set_embedded_elliptic_curve_keys(
|
||||
network: NetworkId,
|
||||
validator: Public,
|
||||
) -> bool {
|
||||
match network {
|
||||
// Validators never need to set embedded elliptic curve keys for Serai
|
||||
NetworkId::Serai => return false,
|
||||
NetworkId::External(network) => {
|
||||
!S::EmbeddedEllipticCurveKeys::contains_key(network, validator)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
mod embedded_elliptic_curve_keys;
|
||||
use embedded_elliptic_curve_keys::*;
|
||||
|
||||
mod allocations;
|
||||
use allocations::*;
|
||||
|
||||
@@ -78,12 +81,7 @@ mod pallet {
|
||||
use frame_support::pallet_prelude::*;
|
||||
|
||||
use serai_primitives::{
|
||||
crypto::KeyPair,
|
||||
network_id::*,
|
||||
coin::*,
|
||||
balance::*,
|
||||
validator_sets::*,
|
||||
address::SeraiAddress,
|
||||
crypto::KeyPair, network_id::*, coin::*, balance::*, validator_sets::*, address::SeraiAddress,
|
||||
};
|
||||
|
||||
use coins_pallet::Pallet as Coins;
|
||||
@@ -91,8 +89,7 @@ mod pallet {
|
||||
use super::*;
|
||||
|
||||
#[pallet::config]
|
||||
#[pallet::disable_frame_system_supertrait_check]
|
||||
pub trait Config: coins_pallet::Config {
|
||||
pub trait Config: frame_system::Config + coins_pallet::Config {
|
||||
type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
|
||||
|
||||
// type ShouldEndSession: ShouldEndSession<BlockNumberFor<Self>>;
|
||||
@@ -157,19 +154,24 @@ mod pallet {
|
||||
}
|
||||
*/
|
||||
|
||||
/// A key on an embedded elliptic curve.
|
||||
struct Abstractions<T: Config>(PhantomData<T>);
|
||||
|
||||
// Satisfy the `EmbeddedEllipticCurveKeys` abstraction
|
||||
|
||||
#[pallet::storage]
|
||||
pub type EmbeddedEllipticCurveKeys<T: Config> = StorageDoubleMap<
|
||||
type EmbeddedEllipticCurveKeys<T: Config> = StorageDoubleMap<
|
||||
_,
|
||||
Blake2_128Concat,
|
||||
Public,
|
||||
Identity,
|
||||
ExternalNetworkId,
|
||||
Blake2_128Concat,
|
||||
Public,
|
||||
serai_primitives::crypto::EmbeddedEllipticCurveKeys,
|
||||
OptionQuery,
|
||||
>;
|
||||
|
||||
struct Abstractions<T: Config>(PhantomData<T>);
|
||||
impl<T: Config> EmbeddedEllipticCurveKeysStorage for Abstractions<T> {
|
||||
type EmbeddedEllipticCurveKeys = EmbeddedEllipticCurveKeys<T>;
|
||||
}
|
||||
|
||||
// Satisfy the `Allocations` abstraction
|
||||
|
||||
@@ -186,7 +188,7 @@ mod pallet {
|
||||
type SortedAllocations = SortedAllocations<T>;
|
||||
}
|
||||
|
||||
// Satisfy the `Sessions` API
|
||||
// Satisfy the `Sessions` abstraction
|
||||
|
||||
// We use `Identity` as the hasher for `NetworkId` due to how constrained it is
|
||||
#[pallet::storage]
|
||||
@@ -809,12 +811,12 @@ mod pallet {
|
||||
#[pallet::weight(0)] // TODO
|
||||
pub fn set_embedded_elliptic_curve_keys(
|
||||
origin: OriginFor<T>,
|
||||
network: ExternalNetworkId,
|
||||
keys: serai_primitives::crypto::EmbeddedEllipticCurveKeys,
|
||||
keys: serai_primitives::crypto::SignedEmbeddedEllipticCurveKeys,
|
||||
) -> DispatchResult {
|
||||
let signer = ensure_signed(origin)?;
|
||||
// TODO: Add PoKs and check validity
|
||||
EmbeddedEllipticCurveKeys::<T>::set(signer, network, Some(keys));
|
||||
<Abstractions<T> as crate::EmbeddedEllipticCurveKeys>::set_embedded_elliptic_curve_keys(
|
||||
signer, keys,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -824,10 +826,12 @@ mod pallet {
|
||||
let validator = ensure_signed(origin)?;
|
||||
// If this network utilizes embedded elliptic curve(s), require the validator to have set the
|
||||
// appropriate key(s)
|
||||
if let Ok(network) = ExternalNetworkId::try_from(network) {
|
||||
if !EmbeddedEllipticCurveKeys::<T>::contains_key(validator, network) {
|
||||
Err(Error::<T>::MissingEmbeddedEllipticCurveKey)?;
|
||||
}
|
||||
if <
|
||||
Abstractions::<T>
|
||||
as
|
||||
crate::EmbeddedEllipticCurveKeys
|
||||
>::still_needs_to_set_embedded_elliptic_curve_keys(network, validator) {
|
||||
Err(Error::<T>::MissingEmbeddedEllipticCurveKey)?;
|
||||
}
|
||||
Coins::<T>::transfer_internal(
|
||||
validator,
|
||||
|
||||
@@ -44,7 +44,8 @@ pub(crate) trait SessionsStorage: AllocationsStorage {
|
||||
///
|
||||
/// This is opaque and to be exclusively read/write by `Sessions`.
|
||||
// The value is how many key shares the validator has.
|
||||
type SelectedValidators: StorageMap<SelectedValidatorsKey, u64> + StoragePrefixedMap<u64>;
|
||||
type SelectedValidators: StorageMap<SelectedValidatorsKey, u64, Query = Option<u64>>
|
||||
+ StoragePrefixedMap<u64>;
|
||||
|
||||
/// The total allocated stake for a network.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user