diff --git a/demo/primitives/src/lib.rs b/demo/primitives/src/lib.rs index eacaf7185aa87..d93b75f3954e4 100644 --- a/demo/primitives/src/lib.rs +++ b/demo/primitives/src/lib.rs @@ -40,7 +40,7 @@ use rstd::prelude::*; use runtime_primitives::generic; #[cfg(feature = "std")] use primitives::bytes; -use runtime_primitives::traits::{BlakeTwo256, DigestItem}; +use runtime_primitives::traits::BlakeTwo256; /// An index to a block. pub type BlockNumber = u64; @@ -73,25 +73,12 @@ pub type Signature = runtime_primitives::Ed25519Signature; pub type Timestamp = u64; /// Header type. -pub type Header = generic::Header; +pub type Header = generic::Header>; /// Block type. pub type Block = generic::Block; /// Block ID. pub type BlockId = generic::BlockId; -/// A log entry in the block. -#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Log(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); - -//TODO: remove this. Generic primitives should not require DigestItem -impl DigestItem for Log { - type AuthoritiesChange = (); - fn as_authorities_change(&self) -> Option<&()> { - unreachable!() - } -} - /// Opaque, encoded, unchecked extrinsic. #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index 8a93fef97e782..80ef5647588c7 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -64,6 +64,7 @@ use demo_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index use runtime_primitives::generic; use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem}; use version::RuntimeVersion; +use codec::{Encode, Decode, Input}; use council::motions as council_motions; use substrate_primitives::u32_trait::{_2, _4}; @@ -202,8 +203,8 @@ impl_outer_event! { } impl_outer_log! { - pub enum Log for Runtime { - consensus + pub enum Log(InternalLog: DigestItem) for Runtime { + consensus(AuthoritiesChange) } } @@ -243,11 +244,11 @@ impl_outer_config! { } impl DigestItem for Log { - type AuthoritiesChange = consensus::AuthoritiesChange; + type AuthorityId = SessionKey; - fn as_authorities_change(&self) -> Option<&Self::AuthoritiesChange> { - match *self { - Log::consensus(ref item) => item.as_authorities_change(), + fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> { + match self.0 { + InternalLog::consensus(ref item) => item.as_authorities_change(), } } } diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 6c8c6bb1c82ee..04e6d8dddfd6b 100644 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index 783b2e6f41721..6a5fdb99d0087 100755 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index c1f5e2bf532f0..1794012886159 100644 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index b5943d520bd88..31e382242fb91 100755 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/runtime-support/src/lib.rs b/substrate/runtime-support/src/lib.rs index 57c8662882858..82c69428dc6de 100644 --- a/substrate/runtime-support/src/lib.rs +++ b/substrate/runtime-support/src/lib.rs @@ -174,27 +174,3 @@ macro_rules! impl_outer_origin { } } } - -#[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) - } - } - )* - }; -} diff --git a/substrate/runtime/consensus/src/lib.rs b/substrate/runtime/consensus/src/lib.rs index 3e0be21131bcc..852b93bcdfc23 100644 --- a/substrate/runtime/consensus/src/lib.rs +++ b/substrate/runtime/consensus/src/lib.rs @@ -46,7 +46,7 @@ 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, OnFinalise, Member, AuthoritiesChangeDigest}; +use primitives::traits::{MaybeSerializeDebug, OnFinalise, Member, DigestItem}; use primitives::bft::MisbehaviorReport; use system::{ensure_signed, ensure_inherent, ensure_root}; @@ -80,31 +80,25 @@ pub type Log = RawLog< ::SessionKey, >; -/// An logs in this module. +/// A logs in this module. #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] #[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum RawLog { /// Authorities set has been changed. Contains the new set of authorities. - AuthoritiesChange(AuthoritiesChange), + AuthoritiesChange(Vec), } -impl RawLog { +impl DigestItem for RawLog { + type AuthorityId = SessionKey; + /// Try to cast the log entry as AuthoritiesChange log entry. - pub fn as_authorities_change(&self) -> Option<&AuthoritiesChange> { + fn as_authorities_change(&self) -> Option<&[SessionKey]> { match *self { - RawLog::AuthoritiesChange(ref item) => Some(item), + 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 { - /// New set of authorities. - pub new_authorities: Vec, -} - // Implementation for tests outside of this crate. impl From> for u64 { fn from(log: RawLog) -> u64 { @@ -114,14 +108,6 @@ impl From> for u64 { } } -impl AuthoritiesChangeDigest for AuthoritiesChange { - 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; diff --git a/substrate/runtime/primitives/src/generic/digest.rs b/substrate/runtime/primitives/src/generic/digest.rs new file mode 100644 index 0000000000000..0616ec8914e39 --- /dev/null +++ b/substrate/runtime/primitives/src/generic/digest.rs @@ -0,0 +1,150 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Generic implementation of a digest. + +use rstd::prelude::*; + +use codec::{Decode, Encode, Codec, Input}; +use traits::{self, Member, DigestItem as DigestItemT}; + +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +pub struct Digest { + pub logs: Vec, +} + +impl Default for Digest { + fn default() -> Self { + Digest { logs: Vec::new(), } + } +} + +impl traits::Digest for Digest where + Item: DigestItemT + Codec +{ + type Item = Item; + + fn logs(&self) -> &[Self::Item] { + &self.logs + } + + fn push(&mut self, item: Self::Item) { + self.logs.push(item); + } +} + +/// Digest item that is able to encode/decode 'system' digest items and +/// provide opaque access to other items. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +pub enum DigestItem { + /// System digest item announcing that authorities set has been changed + /// in the block. Contains the new set of authorities. + AuthoritiesChange(Vec), + /// Any 'non-system' digest item, opaque to the native code. + Other(Vec), +} + +/// A 'referencing view' for digest item. Does not own its contents. Used by +/// final runtime implementations for encoding/decoding its log items. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug))] +pub enum DigestItemRef<'a, AuthorityId: 'a> { + /// Reference to `DigestItem::AuthoritiesChange`. + AuthoritiesChange(&'a [AuthorityId]), + /// Reference to `DigestItem::Other`. + Other(&'a Vec), +} + +/// Type of the digest item. Used to gain explicit control over `DigestItem` encoding +/// process. We need an explicit control, because final runtimes are encoding their own +/// digest items using `DigestItemRef` type and we can't auto-derive `Decode` +/// trait for `DigestItemRef`. +#[repr(u32)] +#[derive(Encode, Decode)] +enum DigestItemType { + Other = 0, + AuthoritiesChange, +} + +impl DigestItem { + /// Returns Some if `self` is a `DigestItem::Other`. + pub fn as_other(&self) -> Option<&Vec> { + match *self { + DigestItem::Other(ref v) => Some(v), + _ => None, + } + } + + /// Returns a 'referencing view' for this digest item. + fn dref<'a>(&'a self) -> DigestItemRef<'a, AuthorityId> { + match *self { + DigestItem::AuthoritiesChange(ref v) => DigestItemRef::AuthoritiesChange(v), + DigestItem::Other(ref v) => DigestItemRef::Other(v), + } + } +} + +impl traits::DigestItem for DigestItem { + type AuthorityId = AuthorityId; + + fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> { + match *self { + DigestItem::AuthoritiesChange(ref authorities) => Some(authorities), + _ => None, + } + } +} + +impl Encode for DigestItem { + fn encode(&self) -> Vec { + self.dref().encode() + } +} + +impl Decode for DigestItem { + fn decode(input: &mut I) -> Option { + let item_type: DigestItemType = Decode::decode(input)?; + match item_type { + DigestItemType::AuthoritiesChange => Some(DigestItem::AuthoritiesChange( + Decode::decode(input)?, + )), + DigestItemType::Other => Some(DigestItem::Other( + Decode::decode(input)?, + )), + } + } +} + +impl<'a, AuthorityId: Encode> Encode for DigestItemRef<'a, AuthorityId> { + fn encode(&self) -> Vec { + let mut v = Vec::new(); + + match *self { + DigestItemRef::AuthoritiesChange(authorities) => { + DigestItemType::AuthoritiesChange.encode_to(&mut v); + authorities.encode_to(&mut v); + }, + DigestItemRef::Other(val) => { + DigestItemType::Other.encode_to(&mut v); + val.encode_to(&mut v); + }, + } + + v + } +} diff --git a/substrate/runtime/primitives/src/generic/header.rs b/substrate/runtime/primitives/src/generic/header.rs index fc4b3d0842223..8425a17bb7b26 100644 --- a/substrate/runtime/primitives/src/generic/header.rs +++ b/substrate/runtime/primitives/src/generic/header.rs @@ -14,41 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Generic implementation of a header and digest. +//! Generic implementation of a block header. #[cfg(feature = "std")] use serde::{Deserialize, Deserializer}; -use rstd::prelude::*; use codec::{Decode, Encode, Codec, Input, Output}; use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Hash as HashT, DigestItem as DigestItemT}; - -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -pub struct Digest { - pub logs: Vec, -} - -impl Default for Digest { - fn default() -> Self { - Digest { logs: Vec::new(), } - } -} - -impl traits::Digest for Digest where - Item: DigestItemT + Codec -{ - type Item = Item; - - fn logs(&self) -> &[Self::Item] { - &self.logs - } - - fn push(&mut self, item: Self::Item) { - self.logs.push(item); - } -} +use generic::Digest; /// Abstraction over a block header for a substrate chain. #[derive(PartialEq, Eq, Clone)] @@ -112,7 +86,7 @@ impl Decode for Header where Number: Decode, Hash: HashT, Hash::Output: Decode, - DigestItem: Decode, + DigestItem: DigestItemT + Decode, { fn decode(input: &mut I) -> Option { Some(Header { @@ -129,7 +103,7 @@ impl Encode for Header where Number: Encode, Hash: HashT, Hash::Output: Encode, - DigestItem: Encode, + DigestItem: DigestItemT + Encode, { fn encode_to(&self, dest: &mut T) { dest.push(&self.parent_hash); diff --git a/substrate/runtime/primitives/src/generic/mod.rs b/substrate/runtime/primitives/src/generic/mod.rs index fd56cb4015421..3bb7483d9b654 100644 --- a/substrate/runtime/primitives/src/generic/mod.rs +++ b/substrate/runtime/primitives/src/generic/mod.rs @@ -20,10 +20,12 @@ mod unchecked_extrinsic; mod checked_extrinsic; mod header; mod block; +mod digest; #[cfg(test)] mod tests; pub use self::unchecked_extrinsic::UncheckedExtrinsic; pub use self::checked_extrinsic::CheckedExtrinsic; -pub use self::header::{Header, Digest}; +pub use self::header::Header; pub use self::block::{Block, SignedBlock, BlockId}; +pub use self::digest::{Digest, DigestItem, DigestItemRef}; diff --git a/substrate/runtime/primitives/src/generic/tests.rs b/substrate/runtime/primitives/src/generic/tests.rs index bbe5d00ed36f8..6d22357d1902c 100644 --- a/substrate/runtime/primitives/src/generic/tests.rs +++ b/substrate/runtime/primitives/src/generic/tests.rs @@ -18,10 +18,10 @@ use codec::{Decode, Encode}; use substrate_primitives::{H256, H512}; -use super::{Digest, Header, UncheckedExtrinsic}; +use super::{Digest, Header, DigestItem, UncheckedExtrinsic}; type Block = super::Block< - Header>, + Header>, UncheckedExtrinsic, >; @@ -33,7 +33,10 @@ fn block_roundtrip_serialization() { number: 100_000, state_root: [1u8; 32].into(), extrinsics_root: [2u8; 32].into(), - digest: Digest { logs: vec![vec![1, 2, 3], vec![4, 5, 6]] }, + digest: Digest { logs: vec![ + DigestItem::Other::(vec![1, 2, 3]), + DigestItem::Other::(vec![4, 5, 6]), + ] }, }, extrinsics: vec![ UncheckedExtrinsic::new_signed( @@ -64,3 +67,39 @@ fn block_roundtrip_serialization() { assert_eq!(block, decoded); } } + +#[test] +fn system_digest_item_encoding() { + let item = DigestItem::AuthoritiesChange::(vec![10, 20, 30]); + let encoded = item.encode(); + assert_eq!(encoded, vec![ + // type = DigestItemType::AuthoritiesChange + 1, + // number of items in athorities set + 3, 0, 0, 0, + // authorities + 10, 0, 0, 0, + 20, 0, 0, 0, + 30, 0, 0, 0, + ]); + + let decoded: DigestItem = Decode::decode(&mut &encoded[..]).unwrap(); + assert_eq!(item, decoded); +} + +#[test] +fn non_system_digest_item_encoding() { + let item = DigestItem::Other::(vec![10, 20, 30]); + let encoded = item.encode(); + assert_eq!(encoded, vec![ + // type = DigestItemType::Other + 0, + // length of other data + 3, 0, 0, 0, + // authorities + 10, 20, 30, + ]); + + let decoded: DigestItem = Decode::decode(&mut &encoded[..]).unwrap(); + assert_eq!(item, decoded); +} \ No newline at end of file diff --git a/substrate/runtime/primitives/src/lib.rs b/substrate/runtime/primitives/src/lib.rs index fd0420dc603b8..e9bddc3286d87 100644 --- a/substrate/runtime/primitives/src/lib.rs +++ b/substrate/runtime/primitives/src/lib.rs @@ -242,3 +242,193 @@ macro_rules! impl_outer_config { } } } + +/// Generates enum that contains all possible log entries for the runtime. +/// Every individual module of the runtime that is mentioned, must +/// expose a `Log` and `RawLog` enums. +/// +/// Generated enum is binary-compatible with and could be interpreted +/// as `generic::DigestItem`. +/// +/// Requires `use runtime_primitives::generic;` to be used. +/// +/// Runtime requirements: +/// 1) binary representation of all supported 'system' log items should stay +/// the same. Otherwise, the native code will be unable to read log items +/// generated by previous runtime versions +/// 2) the support of 'system' log items should never be dropped by runtime. +/// Otherwise, native code will lost its ability to read items of this type +/// even if they were generated by the versions which have supported these +/// items. +#[macro_export] +macro_rules! impl_outer_log { + ( + $(#[$attr:meta])* + pub enum $name:ident ($internal:ident: DigestItem<$( $genarg:ty ),*>) for $trait:ident { + $( $module:ident($( $item:ident ),*) ),* + } + ) => { + /// Wrapper for all possible log entries for the `$trait` runtime. Provides binary-compatible + /// `Encode`/`Decode` implementations with the corresponding `generic::DigestItem`. + #[derive(Clone, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + $(#[$attr])* + #[allow(non_camel_case_types)] + pub struct $name($internal); + + /// All possible log entries for the `$trait` runtime. `Encode`/`Decode` implementations + /// are auto-generated => it is not binary-compatible with `generic::DigestItem`. + #[derive(Clone, PartialEq, Eq, Encode, Decode)] + #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + $(#[$attr])* + #[allow(non_camel_case_types)] + enum $internal { + $( + $module($module::Log<$trait>), + )* + } + + impl $name { + /// Try to convert `$name` into `generic::DigestItemRef`. Returns Some when + /// `self` is a 'system' log && it has been marked as 'system' in macro call. + /// Otherwise, None is returned. + #[allow(unreachable_patterns)] + fn dref<'a>(&'a self) -> Option> { + match self.0 { + $($( + $internal::$module($module::RawLog::$item(ref v)) => + Some(generic::DigestItemRef::$item(v)), + )*)* + _ => None, + } + } + } + + impl From> for $name { + /// Converts `generic::DigestItem` into `$name`. If `generic::DigestItem` represents + /// a system item which is supported by the runtime, it is returned. + /// Otherwise we expect a `Other` log item. Trying to convert from anything other + /// will lead to panic in runtime, since the runtime does not supports this 'system' + /// log item. + #[allow(unreachable_patterns)] + fn from(gen: generic::DigestItem<$($genarg),*>) -> Self { + match gen { + $($( + generic::DigestItem::$item(value) => + $name($internal::$module($module::RawLog::$item(value))), + )*)* + _ => gen.as_other() + .and_then(|value| Decode::decode(&mut &value[..])) + .map($name) + .expect("not allowed to fail in runtime"), + } + } + } + + impl Decode for $name { + /// `generic::DigestItem` binray compatible decode. + fn decode(input: &mut I) -> Option { + let gen: generic::DigestItem<$($genarg),*> = Decode::decode(input)?; + Some($name::from(gen)) + } + } + + impl Encode for $name { + /// `generic::DigestItem` binray compatible encode. + fn encode(&self) -> Vec { + match self.dref() { + Some(dref) => dref.encode(), + None => { + let gen: generic::DigestItem<$($genarg),*> = generic::DigestItem::Other(self.0.encode()); + gen.encode() + }, + } + } + } + + $( + impl From<$module::Log<$trait>> for $name { + /// Converts single module log item into `$name`. + fn from(x: $module::Log<$trait>) -> Self { + $name(x.into()) + } + } + + impl From<$module::Log<$trait>> for $internal { + /// Converts single module log item into `$internal`. + fn from(x: $module::Log<$trait>) -> Self { + $internal::$module(x) + } + } + )* + }; +} + +#[cfg(test)] +mod tests { + use codec::{Encode, Decode, Input}; + + pub trait RuntimeT { + type AuthorityId; + } + + pub struct Runtime; + + impl RuntimeT for Runtime { + type AuthorityId = u64; + } + + #[test] + fn impl_outer_log_works() { + mod a { + use super::RuntimeT; + pub type Log = RawLog<::AuthorityId>; + + #[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)] + pub enum RawLog { A1(AuthorityId), AuthoritiesChange(Vec), A3(AuthorityId) } + } + + mod b { + use super::RuntimeT; + pub type Log = RawLog<::AuthorityId>; + + #[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)] + pub enum RawLog { B1(AuthorityId), B2(AuthorityId) } + } + + use super::generic; // required before macro invocation + + // TODO try to avoid redundant brackets: a(AuthoritiesChange), b + impl_outer_log! { + pub enum Log(InternalLog: DigestItem) for Runtime { + a(AuthoritiesChange), b() + } + } + + // encode/decode regular item + let b1: Log = b::RawLog::B1::(777).into(); + let encoded_b1 = b1.encode(); + let decoded_b1: Log = Decode::decode(&mut &encoded_b1[..]).unwrap(); + assert_eq!(b1, decoded_b1); + + // encode/decode system item + let auth_change: Log = a::RawLog::AuthoritiesChange::(vec![100, 200, 300]).into(); + let encoded_auth_change = auth_change.encode(); + let decoded_auth_change: Log = Decode::decode(&mut &encoded_auth_change[..]).unwrap(); + assert_eq!(auth_change, decoded_auth_change); + + // interpret regular item using `generic::DigestItem` + let generic_b1: generic::DigestItem = Decode::decode(&mut &encoded_b1[..]).unwrap(); + match generic_b1 { + generic::DigestItem::Other(_) => (), + _ => panic!("unexpected generic_b1: {:?}", generic_b1), + } + + // interpret system item using `generic::DigestItem` + let generic_auth_change: generic::DigestItem = Decode::decode(&mut &encoded_auth_change[..]).unwrap(); + match generic_auth_change { + generic::DigestItem::AuthoritiesChange(authorities) => assert_eq!(authorities, vec![100, 200, 300]), + _ => panic!("unexpected generic_auth_change: {:?}", generic_auth_change), + } + } +} diff --git a/substrate/runtime/primitives/src/testing.rs b/substrate/runtime/primitives/src/testing.rs index 3442bfedf4729..764828bfe5662 100644 --- a/substrate/runtime/primitives/src/testing.rs +++ b/substrate/runtime/primitives/src/testing.rs @@ -41,8 +41,12 @@ impl traits::Digest for Digest { } } +impl traits::DigestItem for () { + type AuthorityId = (); +} + impl traits::DigestItem for u64 { - type AuthoritiesChange = (); + type AuthorityId = (); } #[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)] diff --git a/substrate/runtime/primitives/src/traits.rs b/substrate/runtime/primitives/src/traits.rs index 5ec2879ad490f..649f8ec2a305f 100644 --- a/substrate/runtime/primitives/src/traits.rs +++ b/substrate/runtime/primitives/src/traits.rs @@ -433,35 +433,10 @@ pub trait Digest: Member + Default { /// /// 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 + type AuthorityId; /// Returns Some if the entry is the `AuthoritiesChange` entry. - fn as_authorities_change(&self) -> Option<&Self::AuthoritiesChange> { + fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> { 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") } -} diff --git a/substrate/test-runtime/src/lib.rs b/substrate/test-runtime/src/lib.rs index 0bf753a9443a4..4cf8c79353d99 100644 --- a/substrate/test-runtime/src/lib.rs +++ b/substrate/test-runtime/src/lib.rs @@ -111,12 +111,14 @@ pub type Hash = H256; pub type BlockNumber = u64; /// Index of a transaction. pub type Index = u64; +/// The item of a block digest. +pub type DigestItem = runtime_primitives::generic::DigestItem; /// The digest of a block. -pub type Digest = runtime_primitives::generic::Digest<()>; +pub type Digest = runtime_primitives::generic::Digest; /// A test block. pub type Block = runtime_primitives::generic::Block; /// A test block's header. -pub type Header = runtime_primitives::generic::Header; +pub type Header = runtime_primitives::generic::Header; /// Run whatever tests we have. pub fn run_tests(mut input: &[u8]) -> Vec { diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index cf8f84941149b..1ea084433d1a5 100644 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index 077f3a03879d3..ae7e0e7a50fbf 100755 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ