mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 07:01:05 +00:00
Slash and prove membership of prior sessions (#2970)
* skeleton for tracking historical sessions * refactor OpaqueKeys * some more skeleton work * adjust session to new OpaqueKeys API * further refactoring of key-type-ids * session gets validator ID parameter * run up against compiler * tweak staking to support new session changes * first run at child storage for deduplication * Make session use `AccountId` as `ValidatorId` * run up against child trie issues * switch to using normal trie but with a fixed prefix * clear out some println * add dedup test * flesh out historical module more * introduce ExposureOf for staking * test the historical module * WASM compiles * tests all compile * do some mock change * fix bulk of tests * fix staking tests * test obsolecence mechanic * Apply suggestions from code review Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * some more style nits * a couple more nits * tweak tries * fix typo thie -> this
This commit is contained in:
committed by
GitHub
parent
bb7ff32e77
commit
7df8e52cfe
@@ -51,6 +51,9 @@ pub mod transaction_validity;
|
||||
/// Re-export these since they're only "kind of" generic.
|
||||
pub use generic::{DigestItem, Digest};
|
||||
|
||||
/// Re-export this since it's part of the API of this crate.
|
||||
pub use substrate_primitives::crypto::{key_types, KeyTypeId};
|
||||
|
||||
/// A message indicating an invalid signature in extrinsic.
|
||||
pub const BAD_SIGNATURE: &str = "bad signature in extrinsic";
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer};
|
||||
use std::{fmt::Debug, ops::Deref, fmt};
|
||||
use crate::codec::{Codec, Encode, Decode};
|
||||
use crate::traits::{self, Checkable, Applyable, BlakeTwo256, OpaqueKeys};
|
||||
use crate::generic;
|
||||
use crate::traits::{self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, TypedKey};
|
||||
use crate::{generic, KeyTypeId};
|
||||
use crate::weights::{Weighable, Weight};
|
||||
pub use substrate_primitives::H256;
|
||||
use substrate_primitives::U256;
|
||||
@@ -37,12 +37,28 @@ impl Into<AuthorityId> for UintAuthorityId {
|
||||
}
|
||||
}
|
||||
|
||||
/// The key-type of the `UintAuthorityId`
|
||||
pub const UINT_DUMMY_KEY: KeyTypeId = 0xdeadbeef;
|
||||
|
||||
impl TypedKey for UintAuthorityId {
|
||||
const KEY_TYPE: KeyTypeId = UINT_DUMMY_KEY;
|
||||
}
|
||||
|
||||
impl OpaqueKeys for UintAuthorityId {
|
||||
fn count() -> usize { 1 }
|
||||
type KeyTypeIds = std::iter::Cloned<std::slice::Iter<'static, KeyTypeId>>;
|
||||
|
||||
fn key_ids() -> Self::KeyTypeIds { [UINT_DUMMY_KEY].iter().cloned() }
|
||||
// Unsafe, i know, but it's test code and it's just there because it's really convenient to
|
||||
// keep `UintAuthorityId` as a u64 under the hood.
|
||||
fn get_raw(&self, _: usize) -> &[u8] { unsafe { &std::mem::transmute::<_, &[u8; 8]>(&self.0)[..] } }
|
||||
fn get<T: Decode>(&self, _: usize) -> Option<T> { self.0.using_encoded(|mut x| T::decode(&mut x)) }
|
||||
fn get_raw(&self, _: KeyTypeId) -> &[u8] {
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
&self.0 as *const _ as *const u8,
|
||||
std::mem::size_of::<u64>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
fn get<T: Decode>(&self, _: KeyTypeId) -> Option<T> { self.0.using_encoded(|mut x| T::decode(&mut x)) }
|
||||
}
|
||||
|
||||
/// Digest item
|
||||
|
||||
@@ -25,6 +25,7 @@ use substrate_primitives::{self, Hasher, Blake2Hasher};
|
||||
use crate::codec::{Codec, Encode, Decode, HasCompact};
|
||||
use crate::transaction_validity::TransactionValidity;
|
||||
use crate::generic::{Digest, DigestItem};
|
||||
pub use substrate_primitives::crypto::TypedKey;
|
||||
pub use integer_sqrt::IntegerSquareRoot;
|
||||
pub use num_traits::{
|
||||
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
|
||||
@@ -162,6 +163,13 @@ impl<T> Convert<T, T> for Identity {
|
||||
fn convert(a: T) -> T { a }
|
||||
}
|
||||
|
||||
/// A structure that performs standard conversion using the standard Rust conversion traits.
|
||||
pub struct ConvertInto;
|
||||
|
||||
impl<A, B: From<A>> Convert<A, B> for ConvertInto {
|
||||
fn convert(a: A) -> B { a.into() }
|
||||
}
|
||||
|
||||
/// A meta trait for arithmetic.
|
||||
///
|
||||
/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
|
||||
@@ -835,12 +843,15 @@ pub trait ValidateUnsigned {
|
||||
/// Opaque datatype that may be destructured into a series of raw byte slices (which represent
|
||||
/// individual keys).
|
||||
pub trait OpaqueKeys: Clone {
|
||||
/// Return the number of encoded keys.
|
||||
fn count() -> usize { 0 }
|
||||
/// Get the raw bytes of key with index `i`.
|
||||
fn get_raw(&self, i: usize) -> &[u8];
|
||||
/// An iterator over the type IDs of keys that this holds.
|
||||
type KeyTypeIds: IntoIterator<Item=super::KeyTypeId>;
|
||||
|
||||
/// Return an iterator over the key-type IDs supported by this set.
|
||||
fn key_ids() -> Self::KeyTypeIds;
|
||||
/// Get the raw bytes of key with key-type ID `i`.
|
||||
fn get_raw(&self, i: super::KeyTypeId) -> &[u8];
|
||||
/// Get the decoded key with index `i`.
|
||||
fn get<T: Decode>(&self, i: usize) -> Option<T> { T::decode(&mut self.get_raw(i)) }
|
||||
fn get<T: Decode>(&self, i: super::KeyTypeId) -> Option<T> { T::decode(&mut self.get_raw(i)) }
|
||||
/// Verify a proof of ownership for the keys.
|
||||
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool { true }
|
||||
}
|
||||
@@ -969,41 +980,62 @@ macro_rules! count {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Just implement `OpaqueKeys` for a given tuple-struct.
|
||||
/// Implement `OpaqueKeys` for a described struct.
|
||||
/// Would be much nicer for this to be converted to `derive` code.
|
||||
///
|
||||
/// Every field type must be equivalent implement `as_ref()`, which is expected
|
||||
/// to hold the standard SCALE-encoded form of that key. This is typically
|
||||
/// just the bytes of the key.
|
||||
///
|
||||
/// ```rust
|
||||
/// use sr_primitives::{impl_opaque_keys, key_types, KeyTypeId};
|
||||
///
|
||||
/// impl_opaque_keys! {
|
||||
/// pub struct Keys {
|
||||
/// #[id(key_types::ED25519)]
|
||||
/// pub ed25519: [u8; 32],
|
||||
/// #[id(key_types::SR25519)]
|
||||
/// pub sr25519: [u8; 32],
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! impl_opaque_keys {
|
||||
(
|
||||
pub struct $name:ident ( $( $t:ty ),* $(,)* );
|
||||
) => {
|
||||
impl_opaque_keys! {
|
||||
pub struct $name ( $( $t ,)* );
|
||||
impl OpaqueKeys for _ {}
|
||||
}
|
||||
};
|
||||
(
|
||||
pub struct $name:ident ( $( $t:ty ),* $(,)* );
|
||||
impl OpaqueKeys for _ {
|
||||
$($rest:tt)*
|
||||
pub struct $name:ident {
|
||||
$(
|
||||
#[id($key_id:expr)]
|
||||
pub $field:ident: $type:ty,
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
#[derive(Default, Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, $crate::serde::Serialize, $crate::serde::Deserialize))]
|
||||
pub struct $name($( pub $t ,)*);
|
||||
pub struct $name {
|
||||
$(
|
||||
pub $field: $type,
|
||||
)*
|
||||
}
|
||||
|
||||
impl $crate::traits::OpaqueKeys for $name {
|
||||
fn count() -> usize {
|
||||
let mut c = 0;
|
||||
$( let _: $t; c += 1; )*
|
||||
c
|
||||
type KeyTypeIds = $crate::rstd::iter::Cloned<
|
||||
$crate::rstd::slice::Iter<'static, $crate::KeyTypeId>
|
||||
>;
|
||||
|
||||
fn key_ids() -> Self::KeyTypeIds {
|
||||
[
|
||||
$($key_id),*
|
||||
].iter().cloned()
|
||||
}
|
||||
fn get_raw(&self, i: usize) -> &[u8] {
|
||||
$crate::count!(impl_opaque_keys (!! self i) $($t),*);
|
||||
&[]
|
||||
|
||||
fn get_raw(&self, i: $crate::KeyTypeId) -> &[u8] {
|
||||
match i {
|
||||
$(
|
||||
i if i == $key_id => self.$field.as_ref(),
|
||||
)*
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
$($rest)*
|
||||
}
|
||||
};
|
||||
( !! $self:ident $param_i:ident $i:tt) => {
|
||||
if $param_i == $i { return $self.$i.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user