Add digest subtypes and update dependencies (#2734)

* Add different digest types for different parts of the code

* Add script to update dependencies

* Remove an old changelog

* `Inherent` → `PreRuntime`
This commit is contained in:
DemiMarie-parity
2019-06-06 16:16:59 -04:00
committed by Gavin Wood
parent eac4ed412e
commit 418d4a0ce0
7 changed files with 166 additions and 38 deletions
@@ -58,34 +58,151 @@ impl<Item> traits::Digest for Digest<Item> where
}
}
/// 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))]
pub enum DigestItem<Hash, AuthorityId, SealSignature> {
/// System digest item announcing that authorities set has been changed
/// in the block. Contains the new set of authorities.
AuthoritiesChange(Vec<AuthorityId>),
/// System digest item that contains the root of changes trie at given
/// block. It is created for every block iff runtime supports changes
/// trie creation.
ChangesTrieRoot(Hash),
/// A message from the runtime to the consensus engine. This should *never*
/// 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. This is only used by native code, and is never seen
/// by runtimes.
Seal(ConsensusEngineId, SealSignature),
/// A pre-runtime digest.
// Macro black magic.
macro_rules! gen_digest_type {
(
$( #[doc = $main_docs:tt] )*
pub enum $main:ident $(<$($main_params: tt),+>)? { }
$(
$( #[doc = $doc_attr:tt] )*
pub enum $n:ident $(<$($t: tt),+>)? {
$(
$( #[doc = $variant_doc:tt] )*
$variant:ident(($($interior: ty),*), $q: tt),
)*
}
)+
) => {
$( #[doc = $main_docs] )*
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum $main $(<$($main_params),+>)? {
$(
$(
$( #[doc = $variant_doc] )*
$variant($($interior),*),
)*
)*
}
gen_digest_type! {
@internal
$main : $main $(<$($main_params),+>)? => $(
$( #[doc = $doc_attr] )*
pub enum $n $(<$($t),+>)? {
$(
$( #[doc = $variant_doc] )*
$variant(($($interior),*), $q),
)*
}
)+
}
};
(
@internal
$main_id:tt : $main:ty => $(
$( #[doc = $doc_attr:tt] )*
pub enum $n:ident $(<$($t: tt),+>)? {
$(
$( #[doc = $variant_doc:tt] )*
$variant:ident(($($interior: ty),*), $q: tt),
)*
}
)+
) => {
$(
$( #[doc = $doc_attr] )*
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum $n $(<$($t),+>)? {
$(
$( #[doc = $variant_doc] )*
$variant($($interior),*),
)*
}
impl<Hash, AuthorityId, SealSignature> From<$n $(<$($t),*>)?>
for $main {
fn from(digest: $n $(<$($t),+>)?) -> Self {
match digest {
$(
$n::$variant $q => $main_id::$variant $q,
)*
}
}
}
)*
};
}
gen_digest_type! {
/// Digest item that is able to encode/decode 'system' digest items and
/// provide opaque access to other items.
///
/// 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
/// these, but this is not (yet) checked.
PreRuntime(ConsensusEngineId, Vec<u8>),
/// Any 'non-system' digest item, opaque to the native code.
Other(Vec<u8>),
/// For all variants that include a `ConsensusEngineId`, consensus engine
/// implementations **MUST** ignore digests that have a `ConsensusEngineId`
/// that is not theirs. Node implementations **MUST** reject digests that
/// have a `ConsensusEngineId` that corresponds to a consensus engine not in
/// use. Node implementations **MUST** reject blocks as malformed if they
/// reject any of the blocks digest. If the runtime supports this, the
/// node that issued the block **SHOULD** be reported as having committed
/// severe misbehavior and punished accordingly. The invalid block, or its
/// hash, **SHOULD** constitute adequate proof of such misbehavior.
pub enum DigestItem<Hash, AuthorityId, SealSignature> {}
/// A digest item that can be produced by consensus engines. Consensus
/// engine implementations **MUST NOT** push digests not in this variant.
/// This **SHOULD** be detected at compile time. If it is not, the behavior
/// of the blockchain is undefined.
pub enum ConsensusDigest<SealSignature> {
/// Put a Seal on it. This **MUST** come after all other `DigestItem`
/// variants. There **MUST** be exactly one `Seal` per consensus engine,
/// and its `ConsensusEngineId` **MUST** be that of the consensus engine
/// that produced it. Runtimes will not see this variant.
Seal((ConsensusEngineId, SealSignature), (a, b)),
/// An inherent 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 these, but this is checked at compile time. Runtimes can
/// (and should) trust these, as with any other inherent. Consensus
/// engines MUST verify them.
PreRuntime((ConsensusEngineId, Vec<u8>), (a, b)),
}
/// A digest item that can be produced by runtimes. Runtime mplementations
/// **MUST NOT** push digests not in this variant. This **SHOULD** be
/// detected at compile time. If it is not, the behavior of the blockchain
/// is undefined.
pub enum RuntimeDigest {
/// A message from the runtime to the consensus engine. This MUST NOT be
/// generated by the native code of any consensus engine, but this is
/// caught at compile time. The `ConsensusEngineId` is that of the
/// consensus engine for which this digest is intended. Consensus
/// engines MUST ignore digests with `ConsensusEngineId`s other than
/// their own.
Consensus((ConsensusEngineId, Vec<u8>), (a, b)),
/// Any 'non-system' digest item, opaque to the native code. Runtimes
/// MUST verify these, and reject any they did not produce. These MUST
/// NOT be produced by native code.
Other((Vec<u8>), (a)),
}
/// A digest item that is reserved for the SRML. Only the SRML is allowed to
/// push these digests. Consensus engines and third-party runtime code
/// **MUST NOT** push digests in this variant. This **SHOULD** be detected
/// at compile time. If it is not, the behavior of the blockchain is
/// undefined.
pub enum SystemDigest<Hash, AuthorityId> {
/// System digest item announcing that authorities set has been changed
/// in the block. Contains the new set of authorities.
AuthoritiesChange((Vec<AuthorityId>), (a)),
/// System digest item that contains the root of changes trie at given
/// block. It is created for every block iff runtime supports changes
/// trie creation.
ChangesTrieRoot((Hash), (a)),
}
}
#[cfg(feature = "std")]
@@ -36,7 +36,9 @@ pub use self::era::{Era, Phase};
pub use self::checked_extrinsic::CheckedExtrinsic;
pub use self::header::Header;
pub use self::block::{Block, SignedBlock, BlockId};
pub use self::digest::{Digest, DigestItem, DigestItemRef};
pub use self::digest::{
Digest, DigestItem, DigestItemRef, ConsensusDigest, RuntimeDigest, SystemDigest,
};
use crate::codec::Encode;
use rstd::prelude::*;