diff --git a/substrate/core/sr-primitives/src/generic/digest.rs b/substrate/core/sr-primitives/src/generic/digest.rs
index 8f7055b84344fb33bc288c2a336fefef1d8c154c..79a2991e5fbc3985c7e403236f5a38c695e3fb58 100644
--- a/substrate/core/sr-primitives/src/generic/digest.rs
+++ b/substrate/core/sr-primitives/src/generic/digest.rs
@@ -74,13 +74,14 @@ pub enum DigestItem<Hash, AuthorityId, SealSignature> {
 	/// be generated by the native code of any consensus engine, but this is not
 	/// checked (yet).
 	Consensus(ConsensusEngineId, Vec<u8>),
-	/// Put a Seal on it.
+	/// Put a Seal on it. This is only used by native code, and is never seen
+	/// by runtimes.
 	Seal(ConsensusEngineId, SealSignature),
 	/// A pre-runtime digest.
 	///
 	/// These are messages from the consensus engine to the runtime, although
 	/// the consensus engine can (and should) read them itself to avoid
-	/// code and state duplication.  It is erroneous for a runtime to produce
+	/// code and state duplication. It is erroneous for a runtime to produce
 	/// these, but this is not (yet) checked.
 	PreRuntime(ConsensusEngineId, Vec<u8>),
 	/// Any 'non-system' digest item, opaque to the native code.
@@ -110,7 +111,8 @@ pub enum DigestItemRef<'a, Hash: 'a, AuthorityId: 'a, SealSignature: 'a> {
 	/// be generated by the native code of any consensus engine, but this is not
 	/// checked (yet).
 	Consensus(&'a ConsensusEngineId, &'a Vec<u8>),
-	/// Put a Seal on it.
+	/// Put a Seal on it. This is only used by native code, and is never seen
+	/// by runtimes.
 	Seal(&'a ConsensusEngineId, &'a SealSignature),
 	/// A pre-runtime digest.
 	///
diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs
index e6cf9142ad9c80a14b29f5f08396c25bc9d970ca..55e03e47f3168b71b70d82fb7b9b8f3a33464ee4 100644
--- a/substrate/core/sr-primitives/src/lib.rs
+++ b/substrate/core/sr-primitives/src/lib.rs
@@ -25,6 +25,8 @@ pub use parity_codec as codec;
 #[cfg(feature = "std")]
 #[doc(hidden)]
 pub use serde;
+#[doc(hidden)]
+pub use rstd;
 
 #[cfg(feature = "std")]
 pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay};
@@ -341,8 +343,8 @@ impl ::rstd::ops::Deref for PerU128 {
 	type Target = u128;
 
 	fn deref(&self) -> &u128 {
-        &self.0
-    }
+		&self.0
+	}
 }
 
 impl codec::CompactAs for PerU128 {
@@ -611,6 +613,69 @@ macro_rules! impl_outer_config {
 	}
 }
 
+// NOTE [`PreRuntime` and `Consensus` are special]
+//
+// We MUST treat `PreRuntime` and `Consensus` variants specially, as they:
+//
+// * have more parameters (both in `generic::DigestItem` and in runtimes)
+// * have a `PhantomData` parameter in the runtime, but not in `generic::DigestItem`
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __parse_pattern_2 {
+	(PreRuntime $module:ident $internal:ident $v1:ident $v2:ident) => {
+		$internal::$module($module::RawLog::PreRuntime(ref $v1, ref $v2, $crate::rstd::marker::PhantomData))
+	};
+	(Consensus $module:ident $internal:ident $v1:ident $v2:ident) => {
+		$internal::$module($module::RawLog::Consensus(ref $v1, ref $v2, $crate::rstd::marker::PhantomData))
+	};
+	($name:ident $module:ident $internal:ident $v1:ident $v2:ident) => {
+		$internal::$module($module::RawLog::$name(ref $v1))
+	};
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __parse_pattern {
+	(PreRuntime $engine_id:pat, $binder:pat) => {
+		$crate::generic::DigestItem::PreRuntime($engine_id, $binder)
+	};
+	(Consensus $engine_id:pat, $binder:pat) => {
+		$crate::generic::DigestItem::Consensus($engine_id, $binder)
+	};
+	($name:ident $engine_id:pat, $binder:pat) => {
+		$crate::generic::DigestItem::$name($binder)
+	};
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __parse_expr {
+	(PreRuntime $engine_id:expr, $module:ident $internal:ident $binder:expr) => {
+		$internal::$module($module::RawLog::PreRuntime($engine_id, $binder, Default::default()))
+	};
+	(Consensus $engine_id:expr, $module:ident $internal:ident $binder:expr) => {
+		$internal::$module($module::RawLog::Consensus($engine_id, $binder, Default::default()))
+	};
+	($name:ident $engine_id:expr, $module:ident $internal:ident $binder:expr) => {
+		$internal::$module($module::RawLog::$name($binder))
+	};
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __parse_expr_2 {
+	(PreRuntime $module:ident $internal:ident $v1:ident $v2:ident) => {
+		$crate::generic::DigestItemRef::PreRuntime($v1, $v2)
+	};
+	(Consensus $module:ident $internal:ident $v1:ident $v2:ident) => {
+		$crate::generic::DigestItemRef::Consensus($v1, $v2)
+	};
+	($name:ident $module:ident $internal:ident $v1:ident $v2:ident) => {
+		$crate::generic::DigestItemRef::$name($v1)
+	};
+}
+
 /// 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.
@@ -631,7 +696,7 @@ macro_rules! impl_outer_log {
 	(
 		$(#[$attr:meta])*
 		pub enum $name:ident ($internal:ident: DigestItem<$( $genarg:ty ),*>) for $trait:ident {
-			$( $module:ident $(<$instance:path>)? ( $( $sitem:ident ),* ) ),*
+			$( $module:ident $(<$instance:path>)? ( $( $sitem:tt ),* ) ),*
 		}
 	) => {
 		/// Wrapper for all possible log entries for the `$trait` runtime. Provides binary-compatible
@@ -650,7 +715,7 @@ macro_rules! impl_outer_log {
 		#[allow(non_camel_case_types)]
 		pub enum InternalLog {
 			$(
-				$module($module::Log<$trait $(, $instance)? >),
+				$module($module::Log <$trait $(, $instance)?>),
 			)*
 		}
 
@@ -662,8 +727,8 @@ macro_rules! impl_outer_log {
 			fn dref<'a>(&'a self) -> Option<$crate::generic::DigestItemRef<'a, $($genarg),*>> {
 				match self.0 {
 					$($(
-					$internal::$module($module::RawLog::$sitem(ref v)) =>
-						Some($crate::generic::DigestItemRef::$sitem(v)),
+					$crate::__parse_pattern_2!($sitem $module $internal a b) =>
+						Some($crate::__parse_expr_2!($sitem $module $internal a b)),
 					)*)*
 					_ => None,
 				}
@@ -688,22 +753,31 @@ macro_rules! impl_outer_log {
 		}
 
 		impl From<$crate::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.
+			/// 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`, `PreDigest`, or `Consensus` log item. Trying to convert
+			/// from anything else will lead to panic at runtime, since the
+			/// runtime does not supports this 'system' log item.
 			#[allow(unreachable_patterns)]
 			fn from(gen: $crate::generic::DigestItem<$($genarg),*>) -> Self {
 				match gen {
 					$($(
-					$crate::generic::DigestItem::$sitem(value) =>
-						$name($internal::$module($module::RawLog::$sitem(value))),
+					$crate::__parse_pattern!($sitem b, a) =>
+						$name($crate::__parse_expr!($sitem b, $module $internal a)),
 					)*)*
-					_ => gen.as_other()
-						.and_then(|value| $crate::codec::Decode::decode(&mut &value[..]))
-						.map($name)
-						.expect("not allowed to fail in runtime"),
+					_ => {
+						if let Some(s) = gen.as_other()
+							.and_then(|value| $crate::codec::Decode::decode(&mut &value[..]))
+							.map($name)
+						{
+							s
+						} else {
+							panic!("we only reach here if the runtime did not handle a digest; \
+									runtimes are required to handle all digests they receive; qed"
+									)
+						}
+					}
 				}
 			}
 		}
@@ -732,16 +806,16 @@ macro_rules! impl_outer_log {
 		}
 
 		$(
-			impl From<$module::Log<$trait $(, $instance)? >> for $name {
+			impl From<$module::Log<$trait $(, $instance)?>> for $name {
 				/// Converts single module log item into `$name`.
 				fn from(x: $module::Log<$trait $(, $instance)? >) -> Self {
 					$name(x.into())
 				}
 			}
 
-			impl From<$module::Log<$trait $(, $instance)? >> for InternalLog {
+			impl From<$module::Log<$trait $(, $instance)?>> for InternalLog {
 				/// Converts single module log item into `$internal`.
-				fn from(x: $module::Log<$trait $(, $instance)? >) -> Self {
+				fn from(x: $module::Log<$trait $(, $instance)?>) -> Self {
 					InternalLog::$module(x)
 				}
 			}
diff --git a/substrate/core/sr-sandbox/without_std.rs b/substrate/core/sr-sandbox/without_std.rs
index 070ca1ddf15cfd9f08e9275f57cea6567c8b3e11..894ba43eb0ccc39795ef89590835591fcfd4d50d 100755
--- a/substrate/core/sr-sandbox/without_std.rs
+++ b/substrate/core/sr-sandbox/without_std.rs
@@ -15,7 +15,7 @@
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
 use rstd::prelude::*;
-use rstd::{slice, marker, mem};
+use rstd::{slice, marker, mem, vec};
 use rstd::rc::Rc;
 use codec::{Decode, Encode};
 use primitives::sandbox as sandbox_primitives;
diff --git a/substrate/node-template/runtime/src/lib.rs b/substrate/node-template/runtime/src/lib.rs
index b09fe7d7876adb92c605c9ab1c85569b0314963e..19f5f36862b12761323d11cf345b746bee87e36f 100644
--- a/substrate/node-template/runtime/src/lib.rs
+++ b/substrate/node-template/runtime/src/lib.rs
@@ -200,7 +200,7 @@ construct_runtime!(
 		System: system::{default, Log(ChangesTrieRoot)},
 		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
 		Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
-		Aura: aura::{Module},
+		Aura: aura::{Module, Log(PreRuntime)},
 		Indices: indices,
 		Balances: balances,
 		Sudo: sudo,
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index e892ceda81bb9cb8ff5ab83bec687a0a4896db67..c31c6b41ccd1d12ad0e6fe8e50ace36459c39482 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: create_runtime_str!("node"),
 	impl_name: create_runtime_str!("substrate-node"),
 	authoring_version: 10,
-	spec_version: 90,
-	impl_version: 91,
+	spec_version: 91,
+	impl_version: 92,
 	apis: RUNTIME_API_VERSIONS,
 };
 
@@ -227,7 +227,7 @@ construct_runtime!(
 		UncheckedExtrinsic = UncheckedExtrinsic
 	{
 		System: system::{default, Log(ChangesTrieRoot)},
-		Aura: aura::{Module, Inherent(Timestamp)},
+		Aura: aura::{Module, Inherent(Timestamp), Log(PreRuntime)},
 		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
 		Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
 		Indices: indices,
diff --git a/substrate/srml/aura/src/lib.rs b/substrate/srml/aura/src/lib.rs
index 3b557e2944a19ddafe21abb3d321873ff6b912a7..bc46e98ec261172b83194e9caa8efa435b108c70 100644
--- a/substrate/srml/aura/src/lib.rs
+++ b/substrate/srml/aura/src/lib.rs
@@ -51,15 +51,19 @@
 pub use timestamp;
 
 use rstd::{result, prelude::*};
+use parity_codec::{Encode, Decode};
 use srml_support::storage::StorageValue;
 use srml_support::{decl_storage, decl_module};
 use primitives::traits::{SaturatedConversion, Saturating, Zero, One};
 use timestamp::OnTimestampSet;
+use rstd::marker::PhantomData;
 #[cfg(feature = "std")]
 use timestamp::TimestampInherentData;
 use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError};
 #[cfg(feature = "std")]
 use inherents::{InherentDataProviders, ProvideInherentData};
+#[cfg(feature = "std")]
+use serde::Serialize;
 
 mod mock;
 mod tests;
@@ -89,6 +93,20 @@ impl AuraInherentData for InherentData {
 	}
 }
 
+/// Logs in this module.
+pub type Log<T> = RawLog<T>;
+
+/// Logs in this module.
+///
+/// The type parameter distinguishes logs belonging to two different runtimes,
+/// which should not be mixed.
+#[cfg_attr(feature = "std", derive(Serialize, Debug))]
+#[derive(Encode, Decode, PartialEq, Eq, Clone)]
+pub enum RawLog<T> {
+	/// AuRa inherent digests
+	PreRuntime([u8; 4], Vec<u8>, PhantomData<T>),
+}
+
 /// Provides the slot duration inherent data for `Aura`.
 #[cfg(feature = "std")]
 pub struct InherentDataProvider {
diff --git a/substrate/srml/babe/src/lib.rs b/substrate/srml/babe/src/lib.rs
index 3e36481151696f58e6dc87c7233f1b5a5730dfb7..e969dee74bfa7b40f7bab3dc2859b515340fee09 100644
--- a/substrate/srml/babe/src/lib.rs
+++ b/substrate/srml/babe/src/lib.rs
@@ -17,19 +17,21 @@
 //! Consensus extension module for BABE consensus.
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![forbid(unsafe_code, warnings)]
+#![forbid(unsafe_code)]
 pub use timestamp;
 
-use rstd::{result, prelude::*};
+use rstd::{result, prelude::*, marker::PhantomData};
 use srml_support::{decl_storage, decl_module};
 use timestamp::{OnTimestampSet, Trait};
 use primitives::traits::{SaturatedConversion, Saturating};
 #[cfg(feature = "std")]
 use timestamp::TimestampInherentData;
-use parity_codec::Decode;
+use parity_codec::{Encode, Decode};
 use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError};
 #[cfg(feature = "std")]
 use inherents::{InherentDataProviders, ProvideInherentData};
+#[cfg(feature = "std")]
+use serde::Serialize;
 
 /// The BABE inherent identifier.
 pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"babeslot";
@@ -56,6 +58,20 @@ impl BabeInherentData for InherentData {
 	}
 }
 
+/// Logs in this module.
+pub type Log<T> = RawLog<T>;
+
+/// Logs in this module.
+///
+/// The type parameter distinguishes logs belonging to two different runtimes,
+/// which should not be mixed.
+#[cfg_attr(feature = "std", derive(Serialize, Debug))]
+#[derive(Encode, Decode, PartialEq, Eq, Clone)]
+pub enum RawLog<T> {
+	/// BABE inherent digests
+	PreRuntime([u8; 4], Vec<u8>, PhantomData<T>),
+}
+
 /// Provides the slot duration inherent data for BABE.
 #[cfg(feature = "std")]
 pub struct InherentDataProvider {
diff --git a/substrate/srml/consensus/src/lib.rs b/substrate/srml/consensus/src/lib.rs
index 696b9d75f4d9732830ddd0154d40203ad64b1bf5..4613981ec5d9e80b52e5598491665883f86dfa5e 100644
--- a/substrate/srml/consensus/src/lib.rs
+++ b/substrate/srml/consensus/src/lib.rs
@@ -221,6 +221,7 @@ impl<T: OnOfflineReport<Vec<u32>>> InherentOfflineReport for InstantFinalityRepo
 	}
 }
 
+/// Logs in this module.
 pub type Log<T> = RawLog<
 	<T as Trait>::SessionKey,
 >;
diff --git a/substrate/srml/contract/src/account_db.rs b/substrate/srml/contract/src/account_db.rs
index 5cae9f05dc1e9669b6d6199b14487085395ee497..2421eab00abb187582503dda96b1866d3d91726b 100644
--- a/substrate/srml/contract/src/account_db.rs
+++ b/substrate/srml/contract/src/account_db.rs
@@ -177,10 +177,10 @@ impl<T: Trait> AccountDb<T> for DirectAccountDb {
 }
 pub struct OverlayAccountDb<'a, T: Trait + 'a> {
 	local: RefCell<ChangeSet<T>>,
-	underlying: &'a AccountDb<T>,
+	underlying: &'a dyn AccountDb<T>,
 }
 impl<'a, T: Trait> OverlayAccountDb<'a, T> {
-	pub fn new(underlying: &'a AccountDb<T>) -> OverlayAccountDb<'a, T> {
+	pub fn new(underlying: &'a dyn AccountDb<T>) -> OverlayAccountDb<'a, T> {
 		OverlayAccountDb {
 			local: RefCell::new(ChangeSet::new()),
 			underlying,