cs_mwc_bch/messages/
block_header.rs1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
2use std::cmp::min;
3use std::io;
4use std::io::{Read, Write};
5use util::{sha256d, Error, Hash256, Result, Serializable};
6
7#[derive(Debug, Default, PartialEq, Eq, Hash, Clone)]
9pub struct BlockHeader {
10 pub version: u32,
12 pub prev_hash: Hash256,
14 pub merkle_root: Hash256,
16 pub timestamp: u32,
18 pub bits: u32,
20 pub nonce: u32,
22}
23
24impl BlockHeader {
25 pub const SIZE: usize = 80;
27
28 pub fn size(&self) -> usize {
30 BlockHeader::SIZE
31 }
32
33 pub fn hash(&self) -> Hash256 {
35 let mut v = Vec::with_capacity(80);
36 v.write_u32::<LittleEndian>(self.version).unwrap();
37 self.prev_hash.write(&mut v).unwrap();
38 self.merkle_root.write(&mut v).unwrap();
39 v.write_u32::<LittleEndian>(self.timestamp).unwrap();
40 v.write_u32::<LittleEndian>(self.bits).unwrap();
41 v.write_u32::<LittleEndian>(self.nonce).unwrap();
42 sha256d(&v)
43 }
44
45 pub fn validate(&self, hash: &Hash256, prev_headers: &[BlockHeader]) -> Result<()> {
47 if prev_headers.len() > 0 {
49 let h = &prev_headers[prev_headers.len() - min(prev_headers.len(), 11)..];
50 let mut timestamps: Vec<u32> = h.iter().map(|x| x.timestamp).collect();
51 timestamps.sort();
52 if self.timestamp < timestamps[timestamps.len() / 2] {
53 let msg = format!("Timestamp is too old: {}", self.timestamp);
54 return Err(Error::BadData(msg));
55 }
56 }
57
58 let target = self.difficulty_target()?;
60 if hash > &target {
61 return Err(Error::BadData("Invalid POW".to_string()));
62 }
63
64 Ok(())
65 }
66
67 fn difficulty_target(&self) -> Result<Hash256> {
69 let exp = (self.bits >> 24) as usize;
70 if exp < 3 || exp > 32 {
71 let msg = format!("Difficulty exponent out of range: {:?}", self.bits);
72 return Err(Error::BadArgument(msg));
73 }
74 let mut difficulty = [0_u8; 32];
75 difficulty[exp - 1] = ((self.bits >> 16) & 0xff) as u8;
76 difficulty[exp - 2] = ((self.bits >> 08) & 0xff) as u8;
77 difficulty[exp - 3] = ((self.bits >> 00) & 0xff) as u8;
78 Ok(Hash256(difficulty))
79 }
80}
81
82impl Serializable<BlockHeader> for BlockHeader {
83 fn read(reader: &mut dyn Read) -> Result<BlockHeader> {
84 let version = reader.read_u32::<LittleEndian>()?;
85 let prev_hash = Hash256::read(reader)?;
86 let merkle_root = Hash256::read(reader)?;
87 let ts = reader.read_u32::<LittleEndian>()?;
88 let bits = reader.read_u32::<LittleEndian>()?;
89 let nonce = reader.read_u32::<LittleEndian>()?;
90 Ok(BlockHeader {
91 version,
92 prev_hash,
93 merkle_root,
94 timestamp: ts,
95 bits,
96 nonce,
97 })
98 }
99
100 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
101 writer.write_u32::<LittleEndian>(self.version)?;
102 self.prev_hash.write(writer)?;
103 self.merkle_root.write(writer)?;
104 writer.write_u32::<LittleEndian>(self.timestamp)?;
105 writer.write_u32::<LittleEndian>(self.bits)?;
106 writer.write_u32::<LittleEndian>(self.nonce)?;
107 Ok(())
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use std::io::Cursor;
115
116 #[test]
117 fn write_read() {
118 let mut v = Vec::new();
119 let block_header = BlockHeader {
120 version: 12345,
121 prev_hash: Hash256::decode(
122 "7766009988776600998877660099887766009988776600998877660099887766",
123 ).unwrap(),
124 merkle_root: Hash256::decode(
125 "2211554433221155443322115544332211554433221155443322115544332211",
126 ).unwrap(),
127 timestamp: 66,
128 bits: 4488,
129 nonce: 9999,
130 };
131 block_header.write(&mut v).unwrap();
132 assert!(v.len() == block_header.size());
133 assert!(BlockHeader::read(&mut Cursor::new(&v)).unwrap() == block_header);
134 }
135
136 #[test]
137 fn hash() {
138 let block_header = BlockHeader {
139 version: 0x00000001,
140 prev_hash: Hash256::decode(
141 "00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81",
142 ).unwrap(),
143 merkle_root: Hash256::decode(
144 "2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3",
145 ).unwrap(),
146 timestamp: 0x4dd7f5c7,
147 bits: 0x1a44b9f2,
148 nonce: 0x9546a142,
149 };
150 let str_hash = block_header.hash().encode();
151 let expected_hash = "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d";
152 assert!(str_hash == expected_hash);
153 }
154
155 #[test]
156 fn validate() {
157 let prev_hash =
158 Hash256::decode("00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81")
159 .unwrap();
160
161 let mut headers = Vec::new();
162 for i in 0..11 {
163 headers.push(BlockHeader {
164 timestamp: i * 10,
165 ..Default::default()
166 });
167 }
168
169 let valid = BlockHeader {
170 version: 0x00000001,
171 prev_hash,
172 merkle_root: Hash256::decode(
173 "2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3",
174 ).unwrap(),
175 timestamp: 0x4dd7f5c7,
176 bits: 0x1a44b9f2,
177 nonce: 0x9546a142,
178 };
179 assert!(valid.validate(&valid.hash(), &headers).is_ok());
180
181 let h = valid.clone();
183 for header in headers.iter_mut() {
184 header.timestamp = valid.timestamp + 1;
185 }
186 assert!(h.validate(&h.hash(), &headers).is_err());
187
188 let mut h = valid.clone();
190 h.nonce = 0;
191 assert!(h.validate(&h.hash(), &headers).is_err());
192 }
193}