Skip to content
This repository has been archived by the owner on May 23, 2024. It is now read-only.

Add MerkleMountainRangeRoot digest item in header #1

Merged
merged 9 commits into from
Mar 20, 2020
36 changes: 34 additions & 2 deletions primitives/runtime/src/generic/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ pub enum DigestItem<Hash> {
/// native code.
ChangesTrieSignal(ChangesTrieSignal),

/// Blockchain history digest item that contains the merkle mountain range root
/// at given block. It is created for providing super light client a commitment
/// of all the previous blocks.
MerkleMountainRangeRoot(Hash),

/// Some other thing. Unsupported and experimental.
Other(Vec<u8>),
}
Expand Down Expand Up @@ -173,6 +178,10 @@ pub enum DigestItemRef<'a, Hash: 'a> {
/// Digest item that contains signal from changes tries manager to the
/// native code.
ChangesTrieSignal(&'a ChangesTrieSignal),

/// Reference to `DigestItem::MerkleMountainRangeRoot`.
MerkleMountainRangeRoot(&'a Hash),

/// Any 'non-system' digest item, opaque to the native code.
Other(&'a Vec<u8>),
}
Expand All @@ -190,6 +199,7 @@ pub enum DigestItemType {
Seal = 5,
PreRuntime = 6,
ChangesTrieSignal = 7,
MerkleMountainRangeRoot = 18,
}

/// Type of a digest item that contains raw data; this also names the consensus engine ID where
Expand All @@ -215,6 +225,7 @@ impl<Hash> DigestItem<Hash> {
DigestItem::Consensus(ref v, ref s) => DigestItemRef::Consensus(v, s),
DigestItem::Seal(ref v, ref s) => DigestItemRef::Seal(v, s),
DigestItem::ChangesTrieSignal(ref s) => DigestItemRef::ChangesTrieSignal(s),
DigestItem::MerkleMountainRangeRoot(ref v) => DigestItemRef::MerkleMountainRangeRoot(v),
DigestItem::Other(ref v) => DigestItemRef::Other(v),
}
}
Expand Down Expand Up @@ -244,6 +255,11 @@ impl<Hash> DigestItem<Hash> {
self.dref().as_changes_trie_signal()
}

/// Returns `Some` if the entry is the `MerkleMountainRangeRoot` entry.
pub fn as_merkle_mountain_range_root(&self) -> Option<&Hash> {
self.dref().as_merkle_mountain_range_root()
}

/// Returns Some if `self` is a `DigestItem::Other`.
pub fn as_other(&self) -> Option<&[u8]> {
match *self {
Expand Down Expand Up @@ -295,6 +311,9 @@ impl<Hash: Decode> Decode for DigestItem<Hash> {
DigestItemType::ChangesTrieSignal => Ok(DigestItem::ChangesTrieSignal(
Decode::decode(input)?,
)),
DigestItemType::MerkleMountainRangeRoot => Ok(DigestItem::MerkleMountainRangeRoot(
Decode::decode(input)?,
)),
DigestItemType::Other => Ok(DigestItem::Other(
Decode::decode(input)?,
)),
Expand Down Expand Up @@ -343,6 +362,14 @@ impl<'a, Hash> DigestItemRef<'a, Hash> {
}
}

/// Cast this digest item into `MerkleMountainRangeRoot`.
pub fn as_merkle_mountain_range_root(&self) -> Option<&'a Hash> {
match *self {
DigestItemRef::MerkleMountainRangeRoot(ref merkle_mountain_range_root) => Some(merkle_mountain_range_root),
_ => None,
}
}

/// Cast this digest item into `PreRuntime`
pub fn as_other(&self) -> Option<&'a [u8]> {
match *self {
Expand Down Expand Up @@ -396,6 +423,10 @@ impl<'a, Hash: Encode> Encode for DigestItemRef<'a, Hash> {
DigestItemType::ChangesTrieSignal.encode_to(&mut v);
changes_trie_signal.encode_to(&mut v);
},
DigestItemRef::MerkleMountainRangeRoot(merkle_mountain_range_root) => {
DigestItemType::MerkleMountainRangeRoot.encode_to(&mut v);
merkle_mountain_range_root.encode_to(&mut v);
},
DigestItemRef::Other(val) => {
DigestItemType::Other.encode_to(&mut v);
val.encode_to(&mut v);
Expand Down Expand Up @@ -427,13 +458,14 @@ mod tests {
logs: vec![
DigestItem::ChangesTrieRoot(4),
DigestItem::Other(vec![1, 2, 3]),
DigestItem::Seal(*b"test", vec![1, 2, 3])
DigestItem::Seal(*b"test", vec![1, 2, 3]),
DigestItem::MerkleMountainRangeRoot(5),
],
};

assert_eq!(
::serde_json::to_string(&digest).unwrap(),
r#"{"logs":["0x0204000000","0x000c010203","0x05746573740c010203"]}"#
r#"{"logs":["0x0204000000","0x000c010203","0x05746573740c010203","0x1205000000"]}"#
);
}
}
22 changes: 22 additions & 0 deletions primitives/runtime/src/generic/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,25 @@ fn non_system_digest_item_encoding() {
let decoded: DigestItem<H256> = Decode::decode(&mut &encoded[..]).unwrap();
assert_eq!(item, decoded);
}

#[test]
fn non_system_mmr_digest_item_encoding() {
let item = DigestItem::MerkleMountainRangeRoot::<H256>(H256::default());
let encoded = item.encode();
assert_eq!(encoded, vec![
// type = DigestItemType::ChangesTrieRoot
hackfisher marked this conversation as resolved.
Show resolved Hide resolved
18,
// trie root
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
]);

let decoded: DigestItem<H256> = Decode::decode(&mut &encoded[..]).unwrap();
assert_eq!(item, decoded);
}