oasis_core_runtime/consensus/roothash/
block.rs1use crate::common::{crypto::hash::Hash, namespace::Namespace};
8
9#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
15pub struct Block {
16 pub header: Header,
18}
19
20impl Block {
21 pub fn new_genesis_block(id: Namespace, timestamp: u64) -> Block {
23 Block {
24 header: Header {
25 version: 0,
26 round: 0,
27 timestamp,
28 header_type: HeaderType::Normal,
29 namespace: id,
30 previous_hash: Hash::empty_hash(),
31 io_root: Hash::empty_hash(),
32 state_root: Hash::empty_hash(),
33 messages_hash: Hash::empty_hash(),
34 in_msgs_hash: Hash::empty_hash(),
35 },
36 }
37 }
38
39 pub fn new_empty_block(child: &Block, timestamp: u64, header_type: HeaderType) -> Block {
41 Block {
42 header: Header {
43 version: child.header.version,
44 namespace: child.header.namespace,
45 round: child.header.round + 1,
46 timestamp,
47 header_type,
48 previous_hash: child.header.encoded_hash(),
49 io_root: Hash::empty_hash(),
50 state_root: child.header.state_root,
52 messages_hash: Hash::empty_hash(),
53 in_msgs_hash: Hash::empty_hash(),
54 },
55 }
56 }
57}
58
59#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
65#[repr(u8)]
66pub enum HeaderType {
67 #[default]
68 Invalid = 0,
69 Normal = 1,
70 RoundFailed = 2,
71 EpochTransition = 3,
72 Suspended = 4,
73}
74
75#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
81pub struct Header {
82 pub version: u16,
84 pub namespace: Namespace,
86 pub round: u64,
88 pub timestamp: u64,
90 pub header_type: HeaderType,
92 pub previous_hash: Hash,
94 pub io_root: Hash,
96 pub state_root: Hash,
98 pub messages_hash: Hash,
100 pub in_msgs_hash: Hash,
102}
103
104impl Header {
105 pub fn encoded_hash(&self) -> Hash {
107 Hash::digest_bytes(&cbor::to_vec(self.clone()))
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn test_consistent_hash_header() {
117 let empty = Header::default();
119 assert_eq!(
120 empty.encoded_hash(),
121 Hash::from("677ad1a6b9f5e99ed94e5d598b6f92a4641a5f952f2d753b2a6122b6dceeb792")
122 );
123
124 let populated = Header {
125 version: 42,
126 namespace: Namespace::from(Hash::empty_hash().as_ref()),
127 round: 1000,
128 timestamp: 1560257841,
129 header_type: HeaderType::RoundFailed,
130 previous_hash: empty.encoded_hash(),
131 io_root: Hash::empty_hash(),
132 state_root: Hash::empty_hash(),
133 messages_hash: Hash::empty_hash(),
134 in_msgs_hash: Hash::empty_hash(),
135 };
136 assert_eq!(
137 populated.encoded_hash(),
138 Hash::from("b17374d9b36796752a787d0726ef44826bfdb3ece52545e126c8e7592663544d")
139 );
140 }
141}