DigestItem trait (v3) (#687)

* DigestItem v4

* tests

* wording
This commit is contained in:
Svyatoslav Nikolsky
2018-09-10 19:34:51 +03:00
committed by Gav Wood
parent 153439aeea
commit 0e1023ae42
18 changed files with 417 additions and 131 deletions
+2 -15
View File
@@ -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<BlockNumber, BlakeTwo256, Log>;
pub type Header = generic::Header<BlockNumber, BlakeTwo256, generic::DigestItem<()>>;
/// Block type.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// Block ID.
pub type BlockId = generic::BlockId<Block>;
/// 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<u8>);
//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))]
+7 -6
View File
@@ -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<SessionKey>) for Runtime {
consensus(AuthoritiesChange)
}
}
@@ -243,11 +244,11 @@ impl_outer_config! {
}
impl DigestItem for Log {
type AuthoritiesChange = consensus::AuthoritiesChange<SessionKey>;
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(),
}
}
}
@@ -187,27 +187,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)
}
}
)*
};
}
@@ -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<T> = RawLog<
<T as Trait>::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<SessionKey> {
/// Authorities set has been changed. Contains the new set of authorities.
AuthoritiesChange(AuthoritiesChange<SessionKey>),
AuthoritiesChange(Vec<SessionKey>),
}
impl<SessionKey> RawLog<SessionKey> {
impl<SessionKey: Member> DigestItem for RawLog<SessionKey> {
type AuthorityId = SessionKey;
/// Try to cast the log entry as AuthoritiesChange log entry.
pub fn as_authorities_change(&self) -> Option<&AuthoritiesChange<SessionKey>> {
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<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 {
@@ -114,14 +108,6 @@ impl<N> From<RawLog<N>> for u64 {
}
}
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;
@@ -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 <http://www.gnu.org/licenses/>.
//! 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<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: 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<AuthorityId> {
/// System digest item announcing that authorities set has been changed
/// in the block. Contains the new set of authorities.
AuthoritiesChange(Vec<AuthorityId>),
/// Any 'non-system' digest item, opaque to the native code.
Other(Vec<u8>),
}
/// 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<u8>),
}
/// 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<AuthorityId> DigestItem<AuthorityId> {
/// Returns Some if `self` is a `DigestItem::Other`.
pub fn as_other(&self) -> Option<&Vec<u8>> {
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<AuthorityId: Member> traits::DigestItem for DigestItem<AuthorityId> {
type AuthorityId = AuthorityId;
fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> {
match *self {
DigestItem::AuthoritiesChange(ref authorities) => Some(authorities),
_ => None,
}
}
}
impl<AuthorityId: Encode> Encode for DigestItem<AuthorityId> {
fn encode(&self) -> Vec<u8> {
self.dref().encode()
}
}
impl<AuthorityId: Decode> Decode for DigestItem<AuthorityId> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
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<u8> {
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
}
}
@@ -14,41 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! 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<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: 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<Number, Hash, DigestItem> Decode for Header<Number, Hash, DigestItem> where
Number: Decode,
Hash: HashT,
Hash::Output: Decode,
DigestItem: Decode,
DigestItem: DigestItemT + Decode,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Header {
@@ -129,7 +103,7 @@ impl<Number, Hash, DigestItem> Encode for Header<Number, Hash, DigestItem> where
Number: Encode,
Hash: HashT,
Hash::Output: Encode,
DigestItem: Encode,
DigestItem: DigestItemT + Encode,
{
fn encode_to<T: Output>(&self, dest: &mut T) {
dest.push(&self.parent_hash);
@@ -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};
@@ -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<u64, ::traits::BlakeTwo256, Vec<u8>>,
Header<u64, ::traits::BlakeTwo256, DigestItem<u32>>,
UncheckedExtrinsic<H256, u64, u64, ::Ed25519Signature>,
>;
@@ -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::<u32>(vec![1, 2, 3]),
DigestItem::Other::<u32>(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::<u32>(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<u32> = Decode::decode(&mut &encoded[..]).unwrap();
assert_eq!(item, decoded);
}
#[test]
fn non_system_digest_item_encoding() {
let item = DigestItem::Other::<u32>(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<u32> = Decode::decode(&mut &encoded[..]).unwrap();
assert_eq!(item, decoded);
}
@@ -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<generic::DigestItemRef<'a, $($genarg),*>> {
match self.0 {
$($(
$internal::$module($module::RawLog::$item(ref v)) =>
Some(generic::DigestItemRef::$item(v)),
)*)*
_ => None,
}
}
}
impl From<generic::DigestItem<$($genarg),*>> 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<I: Input>(input: &mut I) -> Option<Self> {
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<u8> {
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<R> = RawLog<<R as RuntimeT>::AuthorityId>;
#[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<AuthorityId> { A1(AuthorityId), AuthoritiesChange(Vec<AuthorityId>), A3(AuthorityId) }
}
mod b {
use super::RuntimeT;
pub type Log<R> = RawLog<<R as RuntimeT>::AuthorityId>;
#[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<AuthorityId> { 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<u64>) for Runtime {
a(AuthoritiesChange), b()
}
}
// encode/decode regular item
let b1: Log = b::RawLog::B1::<u64>(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::<u64>(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<u64> = 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<u64> = 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),
}
}
}
@@ -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)]
@@ -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") }
}
+4 -2
View File
@@ -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<u64>;
/// The digest of a block.
pub type Digest = runtime_primitives::generic::Digest<()>;
pub type Digest = runtime_primitives::generic::Digest<DigestItem>;
/// 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, ()>;
pub type Header = runtime_primitives::generic::Header<BlockNumber, BlakeTwo256, DigestItem>;
/// Run whatever tests we have.
pub fn run_tests(mut input: &[u8]) -> Vec<u8> {