mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-01 19:27:58 +00:00
DigestItem trait (v2) (#650)
* DigestItem trait * removed autoimpl in impl_outer_log * StubDigestItem -> ()
This commit is contained in:
committed by
Gav Wood
parent
101f5ec393
commit
be7cb74b06
Generated
+1
@@ -2729,6 +2729,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-primitives 0.1.0",
|
||||
|
||||
@@ -53,10 +53,9 @@ extern crate substrate_runtime_timestamp as timestamp;
|
||||
extern crate substrate_runtime_version as version;
|
||||
extern crate demo_primitives;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use demo_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature};
|
||||
use runtime_primitives::generic;
|
||||
use runtime_primitives::traits::{Convert, BlakeTwo256};
|
||||
use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem};
|
||||
use version::RuntimeVersion;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
@@ -90,9 +89,9 @@ impl system::Trait for Runtime {
|
||||
type BlockNumber = BlockNumber;
|
||||
type Hash = Hash;
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = generic::Digest<Vec<u8>>;
|
||||
type Digest = generic::Digest<Log>;
|
||||
type AccountId = AccountId;
|
||||
type Header = generic::Header<BlockNumber, BlakeTwo256, Vec<u8>>;
|
||||
type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
@@ -112,6 +111,7 @@ pub type Balances = balances::Module<Runtime>;
|
||||
|
||||
impl consensus::Trait for Runtime {
|
||||
const NOTE_OFFLINE_POSITION: u32 = 1;
|
||||
type Log = Log;
|
||||
type SessionKey = SessionKey;
|
||||
type OnOfflineValidator = Staking;
|
||||
}
|
||||
@@ -173,6 +173,22 @@ impl_outer_event! {
|
||||
}
|
||||
}
|
||||
|
||||
impl_outer_log! {
|
||||
pub enum Log for Runtime {
|
||||
consensus
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestItem for Log {
|
||||
type AuthoritiesChange = consensus::AuthoritiesChange<SessionKey>;
|
||||
|
||||
fn as_authorities_change(&self) -> Option<&Self::AuthoritiesChange> {
|
||||
match *self {
|
||||
Log::consensus(ref item) => item.as_authorities_change(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_outer_dispatch! {
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
@@ -203,7 +219,7 @@ impl_outer_dispatch! {
|
||||
/// The address format for describing accounts.
|
||||
pub type Address = balances::Address<Runtime>;
|
||||
/// Block header type as expected by this runtime.
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256, Vec<u8>>;
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
|
||||
/// Block type as expected by this runtime.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// BlockId type as expected by this runtime.
|
||||
|
||||
Generated
+1
@@ -629,6 +629,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-primitives 0.1.0",
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -121,3 +121,27 @@ macro_rules! impl_outer_event {
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_outer_log {
|
||||
|
||||
($(#[$attr:meta])* pub enum $name:ident for $trait:ident { $( $module:ident ),* }) => {
|
||||
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
$(#[$attr])*
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum $name {
|
||||
$(
|
||||
$module($module::Log<$trait>),
|
||||
)*
|
||||
}
|
||||
$(
|
||||
impl From<$module::Log<$trait>> for $name {
|
||||
fn from(x: $module::Log<$trait>) -> Self {
|
||||
$name::$module(x)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ hex-literal = "0.1.0"
|
||||
serde = { version = "1.0", default_features = false }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
substrate-codec = { path = "../../codec", default_features = false }
|
||||
substrate-codec-derive = { path = "../../codec/derive", default_features = false }
|
||||
substrate-primitives = { path = "../../primitives", default_features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
|
||||
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
|
||||
@@ -21,6 +22,7 @@ std = [
|
||||
"serde/std",
|
||||
"serde_derive",
|
||||
"substrate-codec/std",
|
||||
"substrate-codec-derive/std",
|
||||
"substrate-primitives/std",
|
||||
"substrate-runtime-std/std",
|
||||
"substrate-runtime-io/std",
|
||||
|
||||
@@ -32,6 +32,9 @@ extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
extern crate substrate_runtime_primitives as primitives;
|
||||
extern crate substrate_codec as codec;
|
||||
@@ -41,8 +44,9 @@ extern crate substrate_primitives;
|
||||
use rstd::prelude::*;
|
||||
use runtime_support::{storage, Parameter};
|
||||
use runtime_support::dispatch::Result;
|
||||
use runtime_support::storage::StorageValue;
|
||||
use runtime_support::storage::unhashed::StorageVec;
|
||||
use primitives::traits::{MaybeSerializeDebug, MaybeEmpty};
|
||||
use primitives::traits::{MaybeSerializeDebug, MaybeEmpty, OnFinalise, Member, AuthoritiesChangeDigest};
|
||||
use primitives::bft::MisbehaviorReport;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
@@ -71,14 +75,71 @@ impl OnOfflineValidator for () {
|
||||
fn on_offline_validator(_validator_index: usize) {}
|
||||
}
|
||||
|
||||
pub type Log<T> = RawLog<
|
||||
<T as Trait>::SessionKey,
|
||||
>;
|
||||
|
||||
/// An logs in this module.
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
|
||||
pub enum RawLog<SessionKey> {
|
||||
/// Authorities set has been changed. Contains the new set of authorities.
|
||||
AuthoritiesChange(AuthoritiesChange<SessionKey>),
|
||||
}
|
||||
|
||||
impl<SessionKey> RawLog<SessionKey> {
|
||||
/// Try to cast the log entry as AuthoritiesChange log entry.
|
||||
pub fn as_authorities_change(&self) -> Option<&AuthoritiesChange<SessionKey>> {
|
||||
match *self {
|
||||
RawLog::AuthoritiesChange(ref item) => Some(item),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Authorities change log entry.
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
|
||||
pub struct AuthoritiesChange<SessionKey> {
|
||||
/// New set of authorities.
|
||||
pub new_authorities: Vec<SessionKey>,
|
||||
}
|
||||
|
||||
// Implementation for tests outside of this crate.
|
||||
impl<N> From<RawLog<N>> for u64 {
|
||||
fn from(log: RawLog<N>) -> u64 {
|
||||
match log {
|
||||
RawLog::AuthoritiesChange(_) => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<SessionKey: Member> AuthoritiesChangeDigest for AuthoritiesChange<SessionKey> {
|
||||
type AuthorityId = SessionKey;
|
||||
|
||||
fn authorities(&self) -> &[Self::AuthorityId] {
|
||||
&self.new_authorities
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Trait: system::Trait {
|
||||
/// The allowed extrinsic position for `note_offline` inherent.
|
||||
const NOTE_OFFLINE_POSITION: u32;
|
||||
|
||||
/// Type for all log entries of this module.
|
||||
type Log: From<Log<Self>> + Into<system::DigestItemOf<Self>>;
|
||||
|
||||
type SessionKey: Parameter + Default + MaybeSerializeDebug;
|
||||
type OnOfflineValidator: OnOfflineValidator;
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as Consensus {
|
||||
// Authorities set actual at the block execution start. IsSome only if
|
||||
// the set has been changed.
|
||||
OriginalAuthorities: Vec<T::SessionKey>;
|
||||
}
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait>;
|
||||
|
||||
@@ -149,12 +210,40 @@ impl<T: Trait> Module<T> {
|
||||
///
|
||||
/// Called by `next_session` only.
|
||||
pub fn set_authorities(authorities: &[T::SessionKey]) {
|
||||
AuthorityStorageVec::<T::SessionKey>::set_items(authorities);
|
||||
let current_authorities = AuthorityStorageVec::<T::SessionKey>::items();
|
||||
if current_authorities != authorities {
|
||||
Self::save_original_authorities(Some(current_authorities));
|
||||
AuthorityStorageVec::<T::SessionKey>::set_items(authorities);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a single authority by index.
|
||||
pub fn set_authority(index: u32, key: &T::SessionKey) {
|
||||
AuthorityStorageVec::<T::SessionKey>::set_item(index, key);
|
||||
let current_authority = AuthorityStorageVec::<T::SessionKey>::item(index);
|
||||
if current_authority != *key {
|
||||
Self::save_original_authorities(None);
|
||||
AuthorityStorageVec::<T::SessionKey>::set_item(index, key);
|
||||
}
|
||||
}
|
||||
|
||||
/// Save original authorities set.
|
||||
fn save_original_authorities(current_authorities: Option<Vec<T::SessionKey>>) {
|
||||
if OriginalAuthorities::<T>::get().is_some() {
|
||||
// if we have already saved original set before, do not overwrite
|
||||
return;
|
||||
}
|
||||
|
||||
<OriginalAuthorities<T>>::put(current_authorities.unwrap_or_else(||
|
||||
AuthorityStorageVec::<T::SessionKey>::items()));
|
||||
}
|
||||
}
|
||||
|
||||
/// Finalization hook for the consensus module.
|
||||
impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
fn on_finalise(_n: T::BlockNumber) {
|
||||
if let Some(_) = <OriginalAuthorities<T>>::take() {
|
||||
// TODO: call Self::deposit_log
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -255,6 +255,7 @@ mod tests {
|
||||
pub struct Test;
|
||||
impl consensus::Trait for Test {
|
||||
const NOTE_OFFLINE_POSITION: u32 = 1;
|
||||
type Log = u64;
|
||||
type SessionKey = u64;
|
||||
type OnOfflineValidator = staking::Module<Test>;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ use rstd::prelude::*;
|
||||
use codec::{Decode, Encode, Codec, Input, Output};
|
||||
use runtime_support::AuxDispatchable;
|
||||
use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Block as BlockT,
|
||||
Header as HeaderT, Hash as HashT};
|
||||
Header as HeaderT, Hash as HashT, DigestItem as DigestItemT};
|
||||
use rstd::ops;
|
||||
use bft::Justification;
|
||||
|
||||
@@ -208,16 +208,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Digest<Item> {
|
||||
pub logs: Vec<Item>,
|
||||
}
|
||||
|
||||
impl<Item> Default for Digest<Item> {
|
||||
fn default() -> Self {
|
||||
Digest { logs: Vec::new(), }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Item> traits::Digest for Digest<Item> where
|
||||
Item: Member + Default + Codec
|
||||
Item: DigestItemT + Codec
|
||||
{
|
||||
type Item = Item;
|
||||
|
||||
fn logs(&self) -> &[Self::Item] {
|
||||
&self.logs
|
||||
}
|
||||
|
||||
fn push(&mut self, item: Self::Item) {
|
||||
self.logs.push(item);
|
||||
}
|
||||
@@ -317,7 +328,7 @@ impl<Number, Hash, DigestItem> Encode for Header<Number, Hash, DigestItem> where
|
||||
impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestItem> where
|
||||
Number: Member + ::rstd::hash::Hash + Copy + Codec + MaybeDisplay + SimpleArithmetic + Codec,
|
||||
Hash: HashT,
|
||||
DigestItem: Member + Default + Codec,
|
||||
DigestItem: DigestItemT + Codec,
|
||||
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
|
||||
{
|
||||
type Number = Number;
|
||||
@@ -356,7 +367,7 @@ impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestIte
|
||||
impl<Number, Hash, DigestItem> Header<Number, Hash, DigestItem> where
|
||||
Number: Member + ::rstd::hash::Hash + Copy + Codec + MaybeDisplay + SimpleArithmetic + Codec,
|
||||
Hash: HashT,
|
||||
DigestItem: Member + Default + Codec,
|
||||
DigestItem: DigestItemT + Codec,
|
||||
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
|
||||
{
|
||||
/// Convenience helper for computing the hash of the header without having
|
||||
|
||||
@@ -31,11 +31,20 @@ pub struct Digest {
|
||||
|
||||
impl traits::Digest for Digest {
|
||||
type Item = u64;
|
||||
|
||||
fn logs(&self) -> &[Self::Item] {
|
||||
&self.logs
|
||||
}
|
||||
|
||||
fn push(&mut self, item: Self::Item) {
|
||||
self.logs.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
impl traits::DigestItem for u64 {
|
||||
type AuthoritiesChange = ();
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
|
||||
@@ -317,13 +317,6 @@ impl<T> MaybeDisplay for T {}
|
||||
pub trait Member: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static {}
|
||||
impl<T: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static> Member for T {}
|
||||
|
||||
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
|
||||
/// each `Codec`.
|
||||
pub trait Digest {
|
||||
type Item: Member;
|
||||
fn push(&mut self, item: Self::Item);
|
||||
}
|
||||
|
||||
/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
|
||||
/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and
|
||||
/// `parent_hash`, as well as a `digest` and a block `number`.
|
||||
@@ -333,7 +326,7 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stat
|
||||
type Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec;
|
||||
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]>;
|
||||
type Hashing: Hash<Output = Self::Hash>;
|
||||
type Digest: Member + Default;
|
||||
type Digest: Digest;
|
||||
|
||||
fn new(
|
||||
number: Self::Number,
|
||||
@@ -429,3 +422,49 @@ pub trait Applyable: Sized + Send + Sync {
|
||||
fn sender(&self) -> &Self::AccountId;
|
||||
fn apply(self) -> Result<(), &'static str>;
|
||||
}
|
||||
|
||||
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
|
||||
/// each `Codec`.
|
||||
pub trait Digest: Member + Default {
|
||||
type Item: DigestItem;
|
||||
fn logs(&self) -> &[Self::Item];
|
||||
fn push(&mut self, item: Self::Item);
|
||||
}
|
||||
|
||||
/// Single digest item. Could be any type that implements `Member` and provides methods
|
||||
/// for casting member to 'system' log items, known to substrate.
|
||||
///
|
||||
/// If the runtime does not supports some 'system' items, use `()` as a stub.
|
||||
pub trait DigestItem: Member {
|
||||
/// Events of this type is raised by the runtime when set of authorities is changed.
|
||||
/// Provides access to the new set of authorities.
|
||||
type AuthoritiesChange: AuthoritiesChangeDigest; // TODO: = () when associated type defaults are stabilized
|
||||
|
||||
/// Returns Some if the entry is the `AuthoritiesChange` entry.
|
||||
fn as_authorities_change(&self) -> Option<&Self::AuthoritiesChange> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Authorities change digest item. Created when the set of authorities is changed
|
||||
/// within the runtime.
|
||||
pub trait AuthoritiesChangeDigest {
|
||||
/// Type of authority Id.
|
||||
type AuthorityId: Member;
|
||||
|
||||
/// Get reference to the new authorities set.
|
||||
fn authorities(&self) -> &[Self::AuthorityId];
|
||||
}
|
||||
|
||||
/// Stub implementations for the digest item that is never created and used.
|
||||
///
|
||||
/// Should be used as a stub for items that are not supported by runtimes.
|
||||
impl DigestItem for () {
|
||||
type AuthoritiesChange = ();
|
||||
}
|
||||
|
||||
impl AuthoritiesChangeDigest for () {
|
||||
type AuthorityId = ();
|
||||
|
||||
fn authorities(&self) -> &[Self::AuthorityId] { unreachable!("() is never created") }
|
||||
}
|
||||
|
||||
@@ -295,6 +295,7 @@ mod tests {
|
||||
pub struct Test;
|
||||
impl consensus::Trait for Test {
|
||||
const NOTE_OFFLINE_POSITION: u32 = 1;
|
||||
type Log = u64;
|
||||
type SessionKey = u64;
|
||||
type OnOfflineValidator = ();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ use {GenesisConfig, Module, Trait, consensus, session, system, timestamp, balanc
|
||||
pub struct Test;
|
||||
impl consensus::Trait for Test {
|
||||
const NOTE_OFFLINE_POSITION: u32 = 1;
|
||||
type Log = u64;
|
||||
type SessionKey = u64;
|
||||
type OnOfflineValidator = ();
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ pub trait Trait: Eq + Clone {
|
||||
type Event: Parameter + Member + From<Event>;
|
||||
}
|
||||
|
||||
pub type DigestItemOf<T> = <<T as Trait>::Digest as traits::Digest>::Item;
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait>;
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ mod tests {
|
||||
}
|
||||
impl consensus::Trait for Test {
|
||||
const NOTE_OFFLINE_POSITION: u32 = 1;
|
||||
type Log = u64;
|
||||
type SessionKey = u64;
|
||||
type OnOfflineValidator = ();
|
||||
}
|
||||
|
||||
@@ -112,11 +112,11 @@ pub type BlockNumber = u64;
|
||||
/// Index of a transaction.
|
||||
pub type Index = u64;
|
||||
/// The digest of a block.
|
||||
pub type Digest = runtime_primitives::generic::Digest<Vec<u8>>;
|
||||
pub type Digest = runtime_primitives::generic::Digest<()>;
|
||||
/// A test block.
|
||||
pub type Block = runtime_primitives::generic::Block<Header, Extrinsic>;
|
||||
/// A test block's header.
|
||||
pub type Header = runtime_primitives::generic::Header<BlockNumber, BlakeTwo256, Vec<u8>>;
|
||||
pub type Header = runtime_primitives::generic::Header<BlockNumber, BlakeTwo256, ()>;
|
||||
|
||||
/// Run whatever tests we have.
|
||||
pub fn run_tests(mut input: &[u8]) -> Vec<u8> {
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user