1use std::io;
19
20#[cfg(feature = "serde")] use serde::{Deserialize, Deserializer, Serialize, Serializer};
21#[cfg(feature = "serde")] use std::fmt;
22
23use crate::dynafed;
24use crate::hashes::{Hash, sha256};
25use crate::Transaction;
26use crate::encode::{self, serialize, Decodable, Encodable, VarInt};
27use crate::{BlockHash, Script, TxMerkleNode};
28
29#[derive(Clone, Debug, Eq, Hash, PartialEq)]
31pub enum ExtData {
32 Proof {
34 challenge: Script,
36 solution: Script,
38 },
39 Dynafed {
41 current: dynafed::Params,
43 proposed: dynafed::Params,
45 signblock_witness: Vec<Vec<u8>>,
47 },
48}
49
50#[cfg(feature = "serde")]
51impl<'de> Deserialize<'de> for ExtData {
52 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
53 use serde::de;
54
55 enum Enum { Unknown, Challenge, Solution, Current, Proposed, Witness }
56 struct EnumVisitor;
57
58 impl de::Visitor<'_> for EnumVisitor {
59 type Value = Enum;
60
61 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 f.write_str("a field name")
63 }
64
65 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
66 match v {
67 "challenge" => Ok(Enum::Challenge),
68 "solution" => Ok(Enum::Solution),
69 "current" => Ok(Enum::Current),
70 "proposed" => Ok(Enum::Proposed),
71 "signblock_witness" => Ok(Enum::Witness),
72 _ => Ok(Enum::Unknown),
73 }
74 }
75 }
76
77 impl<'de> Deserialize<'de> for Enum {
78 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
79 d.deserialize_str(EnumVisitor)
80 }
81 }
82
83 struct Visitor;
84 impl<'de> de::Visitor<'de> for Visitor {
85 type Value = ExtData;
86
87 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
88 f.write_str("block header extra data")
89 }
90
91 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
92 where
93 A: de::MapAccess<'de>,
94 {
95 let mut challenge = None;
96 let mut solution = None;
97 let mut current = None;
98 let mut proposed = None;
99 let mut witness = None;
100
101 loop {
102 match map.next_key::<Enum>()? {
103 Some(Enum::Unknown) => {
104 map.next_value::<de::IgnoredAny>()?;
105 },
106 Some(Enum::Challenge) => challenge = Some(map.next_value()?),
107 Some(Enum::Solution) => solution = Some(map.next_value()?),
108 Some(Enum::Current) => current = Some(map.next_value()?),
109 Some(Enum::Proposed) => proposed = Some(map.next_value()?),
110 Some(Enum::Witness) => witness = Some(map.next_value()?),
111 None => { break; }
112 }
113 }
114
115 let challenge_missing = challenge.is_some();
116 if let (Some(chal), Some(soln)) = (challenge, solution) {
117 Ok(ExtData::Proof {
118 challenge: chal,
119 solution: soln,
120 })
121 } else if let (Some(cur), Some(prop), Some(wit))
122 = (current, proposed, witness)
123 {
124 Ok(ExtData::Dynafed {
125 current: cur,
126 proposed: prop,
127 signblock_witness: wit,
128 })
129 } else if challenge_missing {
130 Err(de::Error::missing_field("challenge"))
131 } else {
132 Err(de::Error::missing_field("solution"))
133 }
134 }
135 }
136
137 static FIELDS: &[&str] = &[
138 "challenge",
139 "solution",
140 "current",
141 "proposed",
142 "signblock_witness",
143 ];
144 d.deserialize_struct("ExtData", FIELDS, Visitor)
145 }
146}
147
148#[cfg(feature = "serde")]
149impl Serialize for ExtData {
150 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
151 use serde::ser::SerializeStruct;
152
153 match *self {
154 ExtData::Proof { ref challenge, ref solution } => {
155 let mut st = s.serialize_struct("ExtData", 2)?;
156 st.serialize_field("challenge", challenge)?;
157 st.serialize_field("solution", solution)?;
158 st.end()
159 },
160 ExtData::Dynafed { ref current, ref proposed, ref signblock_witness } => {
161 let mut st = s.serialize_struct("ExtData", 3)?;
162 st.serialize_field("current", current)?;
163 st.serialize_field("proposed", proposed)?;
164 st.serialize_field("signblock_witness", signblock_witness)?;
165 st.end()
166 },
167 }
168 }
169}
170
171impl Encodable for ExtData {
172 fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, encode::Error> {
173 Ok(match *self {
174 ExtData::Proof {
175 ref challenge,
176 ref solution,
177 } => {
178 challenge.consensus_encode(&mut s)? +
179 solution.consensus_encode(&mut s)?
180 },
181 ExtData::Dynafed {
182 ref current,
183 ref proposed,
184 ref signblock_witness,
185 } => {
186 current.consensus_encode(&mut s)? +
187 proposed.consensus_encode(&mut s)? +
188 signblock_witness.consensus_encode(&mut s)?
189 },
190 })
191 }
192}
193
194impl Default for ExtData {
195 fn default() -> ExtData {
196 ExtData::Dynafed {
197 current: dynafed::Params::Null,
198 proposed: dynafed::Params::Null,
199 signblock_witness: vec![],
200 }
201 }
202}
203
204#[derive(Clone, Debug, Eq, Hash, PartialEq)]
206pub struct BlockHeader {
207 pub version: u32,
209 pub prev_blockhash: BlockHash,
211 pub merkle_root: TxMerkleNode,
213 pub time: u32,
215 pub height: u32,
217 pub ext: ExtData,
219}
220serde_struct_impl!(BlockHeader, version, prev_blockhash, merkle_root, time, height, ext);
221
222impl BlockHeader {
223 pub fn block_hash(&self) -> BlockHash {
225
226 let version = if let ExtData::Dynafed { .. } = self.ext {
227 self.version | 0x8000_0000
228 } else {
229 self.version
230 };
231
232 let mut enc = BlockHash::engine();
234 version.consensus_encode(&mut enc).unwrap();
235 self.prev_blockhash.consensus_encode(&mut enc).unwrap();
236 self.merkle_root.consensus_encode(&mut enc).unwrap();
237 self.time.consensus_encode(&mut enc).unwrap();
238 self.height.consensus_encode(&mut enc).unwrap();
239 match self.ext {
240 ExtData::Proof { ref challenge, .. } => {
241 challenge.consensus_encode(&mut enc).unwrap();
242 },
243 ExtData::Dynafed { ref current, ref proposed, .. } => {
244 current.consensus_encode(&mut enc).unwrap();
245 proposed.consensus_encode(&mut enc).unwrap();
246 },
247 }
248 BlockHash::from_engine(enc)
249 }
250
251 pub fn is_dynafed(&self) -> bool {
253 matches!(self.ext, ExtData::Dynafed { .. })
254 }
255
256 pub fn clear_witness(&mut self) {
260 match &mut self.ext {
261 ExtData::Proof { ref mut solution, .. } => {
262 *solution = Script::new();
263 },
264 ExtData::Dynafed { ref mut signblock_witness, .. } => {
265 signblock_witness.clear();
266 },
267 }
268 }
269
270 pub fn calculate_dynafed_params_root(&self) -> Option<sha256::Midstate> {
272 match self.ext {
273 ExtData::Proof { .. } => None,
274 ExtData::Dynafed { ref current, ref proposed, .. } => {
275 let leaves = [
276 current.calculate_root().to_byte_array(),
277 proposed.calculate_root().to_byte_array(),
278 ];
279 Some(crate::fast_merkle_root::fast_merkle_root(&leaves[..]))
280 }
281 }
282 }
283
284 pub fn dynafed_current(&self) -> Option<&dynafed::Params> {
286 match self.ext {
287 ExtData::Dynafed { ref current, .. } => Some(current),
288 ExtData::Proof { .. } => None,
289 }
290 }
291
292 pub fn dynafed_proposed(&self) -> Option<&dynafed::Params> {
294 match self.ext {
295 ExtData::Dynafed { ref proposed, .. } => Some(proposed),
296 ExtData::Proof { .. } => None,
297 }
298 }
299}
300
301impl Encodable for BlockHeader {
302 fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, encode::Error> {
303 let version = if let ExtData::Dynafed { .. } = self.ext {
304 self.version | 0x8000_0000
305 } else {
306 self.version
307 };
308
309 Ok(version.consensus_encode(&mut s)? +
310 self.prev_blockhash.consensus_encode(&mut s)? +
311 self.merkle_root.consensus_encode(&mut s)? +
312 self.time.consensus_encode(&mut s)? +
313 self.height.consensus_encode(&mut s)? +
314 self.ext.consensus_encode(&mut s)?)
315 }
316}
317
318impl Decodable for BlockHeader {
319 fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
320 let mut version: u32 = Decodable::consensus_decode(&mut d)?;
321 let is_dyna = if version >> 31 == 1 {
322 version &= 0x7fff_ffff;
323 true
324 } else {
325 false
326 };
327
328 Ok(BlockHeader {
329 version,
330 prev_blockhash: Decodable::consensus_decode(&mut d)?,
331 merkle_root: Decodable::consensus_decode(&mut d)?,
332 time: Decodable::consensus_decode(&mut d)?,
333 height: Decodable::consensus_decode(&mut d)?,
334 ext: if is_dyna {
335 ExtData::Dynafed {
336 current: Decodable::consensus_decode(&mut d)?,
337 proposed: Decodable::consensus_decode(&mut d)?,
338 signblock_witness: Decodable::consensus_decode(&mut d)?,
339 }
340 } else {
341 ExtData::Proof {
342 challenge: Decodable::consensus_decode(&mut d)?,
343 solution: Decodable::consensus_decode(&mut d)?,
344 }
345 },
346 })
347 }
348}
349
350#[derive(Clone, Debug, Eq, Hash, PartialEq)]
352pub struct Block {
353 pub header: BlockHeader,
355 pub txdata: Vec<Transaction>,
357}
358serde_struct_impl!(Block, header, txdata);
359impl_consensus_encoding!(Block, header, txdata);
360
361impl Block {
362 pub fn block_hash(&self) -> BlockHash {
364 self.header.block_hash()
365 }
366
367 #[deprecated(since = "0.19.1", note = "Please use `Block::size` instead.")]
369 pub fn get_size(&self) -> usize {
370 self.size()
371 }
372
373 pub fn size(&self) -> usize {
375 let base_size = serialize(&self.header).len() + VarInt(self.txdata.len() as u64).size();
377 let txs_size: usize = self.txdata.iter().map(Transaction::size).sum();
378 base_size + txs_size
379 }
380
381 #[deprecated(since = "0.19.1", note = "Please use `Block::weight` instead.")]
383 pub fn get_weight(&self) -> usize {
384 self.weight()
385 }
386
387 pub fn weight(&self) -> usize {
389 let base_weight = 4 * (serialize(&self.header).len() + VarInt(self.txdata.len() as u64).size());
390 let txs_weight: usize = self.txdata.iter().map(Transaction::weight).sum();
391 base_weight + txs_weight
392 }
393}
394
395#[cfg(test)]
396mod tests {
397 use crate::Block;
398 use crate::hex::FromHex;
399
400 use super::*;
401
402 const SIMPLE_BLOCK: &str = "\
403 00000020a66e4a4baff69735267346d12e59e8a0da848b593813554deb16a6f3\
404 6cd035e9aab0e2451724598471dd4e45f0dca40ca5f4ac62e61957e50925af08\
405 59891fcc8842805b020000000151000102000000010100000000000000000000\
406 00000000000000000000000000000000000000000000ffffffff03520101ffff\
407 ffff0201230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a\
408 0d5de1b201000000000000000000016a01230f4f5d4b7c6fa845806ee4f67713\
409 459e1b69e8e60fcee2e4940c7a0d5de1b201000000000000000000266a24aa21\
410 a9ed94f15ed3a62165e4a0b99699cc28b48e19cb5bc1b1f47155db62d63f1e04\
411 7d45000000000000012000000000000000000000000000000000000000000000\
412 000000000000000000000000000000\
413 ";
414 const DYNAFED_BLOCK: &str = "\
415 000000a0da9d569617d1d65c3390a01c18c4fa7c4d0f4738b6fc2b5c5faf2e8a\
416 463abbaa46eb9123808e1e2ff75e9472fa0f0589b53b7518a69d3d6fcb9228ed\
417 345734ea06b9c45d070000000122002057c555a91edf9552282d88624d1473c2\
418 75e64b7218870eb8fb0335b442976b8d02010000fbee9cea00d8efdc49cfbec3\
419 28537e0d7032194de6ebf3cf42e5c05bb89a08b100040047304402206f55bc87\
420 1387a9840489d47624b02995e774e3b70fed56d1eb43a9a53d4fd3e102201e1c\
421 bfbbd1079f5bea3bc216882d3fefbf6f27aa761820d3a88f12e5a5ea7ff00148\
422 3045022100c072816f6561e73ee6c0ae32d55c3eec4da73b035425e4eb05ab50\
423 772591b4360220311bf295010094a489d9b280d9dafb724d776a1d99b9ede31c\
424 4b59bc2095c5c30169522103cadff18e928133df2e670a3715c4e7a81d357de3\
425 6ddaa5016628e70a3e6a452f21021f0d8638c413ef7769cd711ce84c8f192f5a\
426 85f0fd6d8e63ddb4d2cf6740b23b210296db75c11ea3a292a372f6c94f5013ea\
427 eb379f701857a702f3b83f88da21be6f53ae0102000000010100000000000000\
428 00000000000000000000000000000000000000000000000000ffffffff035701\
429 01ffffffff020137c495f58d698979ff9124e8c7455fe79b13ddb96afa25c458\
430 94eb059868a8c001000000000000000000016a0137c495f58d698979ff9124e8\
431 c7455fe79b13ddb96afa25c45894eb059868a8c001000000000000000000266a\
432 24aa21a9ed94f15ed3a62165e4a0b99699cc28b48e19cb5bc1b1f47155db62d6\
433 3f1e047d45000000000000012000000000000000000000000000000000000000\
434 000000000000000000000000000000000000\
435 ";
436
437 #[cfg(feature = "serde")]
438 #[test]
439 fn blockheader_serde() {
440 let block: Block = hex_deserialize!(&SIMPLE_BLOCK);
441 roundtrip_header(&block.header);
442 let block: Block = hex_deserialize!(&DYNAFED_BLOCK);
443 roundtrip_header(&block.header);
444 }
445 #[cfg(feature = "serde")]
446 fn roundtrip_header(header: &BlockHeader) {
447 let header_ser = serde_json::to_string(header).unwrap();
448 let header_deser: BlockHeader = serde_json::from_str(&header_ser).unwrap();
449
450 assert_eq!(&header_deser, header);
451 let header_ser = serde_cbor::to_vec(header).unwrap();
452 let header_deser: BlockHeader = serde_cbor::from_slice(&header_ser).unwrap();
453
454 assert_eq!(&header_deser, header);
455 }
456
457 #[test]
458 fn block() {
459 let block: Block = hex_deserialize!(SIMPLE_BLOCK);
461
462 assert_eq!(
463 block.block_hash().to_string(),
464 "287ca47e8da47eb8c28d870663450bb026922eadb30a1b2f8293e6e9d1ca5322"
465 );
466 assert_eq!(block.header.version, 0x2000_0000);
467 assert_eq!(block.header.height, 2);
468 assert_eq!(block.txdata.len(), 1);
469 assert_eq!(block.size(), serialize(&block).len());
470 assert_eq!(block.weight(), 1089);
471
472 let block: Block = hex_deserialize!(
474 "000000207e3dba98460e4136659f0fccf3e59338dfe53ed5f094fb0bb94d771c\
475 48341854d875900105c87e5dd46c740cb1129c06f8f4007e868f61b25e37cffa9\
476 46c718d8742805b01000000015100030200000001010000000000000000000000\
477 000000000000000000000000000000000000000000ffffffff03510101fffffff\
478 f0201230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5d\
479 e1b2010000000000009b64001976a914608c0ea8194a8ceb57f0196f44a6b48a5\
480 4fc065988ac01230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e494\
481 0c7a0d5de1b201000000000000000000266a24aa21a9ed8f8a98e5623643b2416\
482 7266c2648ead4a50d18b0491c6f34e11398aaee0ca6e800000000000001200000\
483 00000000000000000000000000000000000000000000000000000000000000000\
484 00000020000000001eb04b68e9a26d116046c76e8ff47332fb71dda90ff4bef53\
485 70f25226d3bc09fc0000000000feffffff0201230f4f5d4b7c6fa845806ee4f67\
486 713459e1b69e8e60fcee2e4940c7a0d5de1b20100000002540bd71c001976a914\
487 48633e2c0ee9495dd3f9c43732c47f4702a362c888ac01230f4f5d4b7c6fa8458\
488 06ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b2010000000000000ce400\
489 0000000000020000000101f23ceddac67cfbbc997199daa651384d0746fb2a548\
490 2b8c8629ba8df4b788f75000000006b483045022100e0feb3e2f292000d67e24b\
491 821d87c9532230dac1de428d6a0068c9f416583abf02200e76f072788dd411b23\
492 27267cd91c6b1659809598cd4fae35be475efe1e4bbad01210201e15c23c02165\
493 2d07c1557b607ea0379fca0462aca840d6c33c4d4927524547feffffff030b604\
494 24a423335923c15ae387d95d4f80d944722020bfa55b9f0a0e67579e3c13c081c\
495 4f215239c77456d121eb73bd9914a9a6398fe369b4eb8f88a5f78e257fcaa3033\
496 01ee46349950886ae115c9556607fcda9381c2f72368f4b5286488c62aa0b0819\
497 76a9148bb6c4d5814d43fefb9e330575e326632136389c88ac0bd436b0539f549\
498 7af792d7cb281f09b73d8a5abc198b3ce6239d79e68893e5e5d0923899fd35071\
499 ba8a209d85b556d5747b6c35539c3b2f8631a27c0d477a1f45a603d1d350b8cbf\
500 900f7666da66541bf6252fc4c162141ad49c670884c93c57db6ba1976a9148c7a\
501 b6e0fca387d03643d4846f708bf39d47c1e988ac01230f4f5d4b7c6fa845806ee\
502 4f67713459e1b69e8e60fcee2e4940c7a0d5de1b2010000000000008e80000000\
503 0000000000000043010001dc65ae13f76fde4a7172e0fb380b1a5cc8dc88eaa06\
504 59e638a25eac8ae30d79bf93eb7e487eeee323e4ac8e3a2fe6523bdeba6acce32\
505 b9b085f2286174c04655fd6c0a6020000000000000000178ad016b3e5d8165423\
506 e56d8b37e3eaee96009b2f970043ccf65d61b5c3c1e1ef343e0c479bdba442717\
507 dc861c9591566010240b9d4607efb9252a5fcef05edf640e0bb6b606729246ad0\
508 7baa49d0d3b52042c65a03ca737744e45b2d2d6d177c36569ae9d6eb4437305b1\
509 69bbc59f85cabff3bc49a2d6d08c177cce3121a509d3c47961bd22e35c932b79d\
510 4ec5ccaf913fac04034bfebdadbc4ff3127af96344b02ee6b967bb08326cbe6a4\
511 e1c924485e64a8c0fdf70b98c99f38acaa15aa0adb2b5b7335ed5502443891bcd\
512 657310347cbd928f40f38f1dec087a2b947c9cf7d304798f77bbc4a2c843796b2\
513 d49acce91de4e88a0a9c261277df28ffc3320d7f7d64790f592ddded48a1068ef\
514 88271395fa5606389ef90856ddd6bd6710a8d27e0147983b5dde2a7efae44e83a\
515 d02a3c3da04be43d5f2c05c205f1e17b48554c2177670f46dbb6600bd2e6c75dd\
516 5ea2e1072c5f22483dcf05d8124e3f9063a5ddb179a29c23a2d15d6e89f2192f0\
517 3dae5938f66fcdcff000c5a96ffd2920f23881880af72153c96a56dd80c218bb4\
518 8b44a18e54a8050ff32c869c1264ee574cdb4002f86e0779c724d11dc4a768dbe\
519 c1bd22054886f1fdf2e7347e4c247b829159d1375f881c6ce0a5c4da8534000e7\
520 fec3a980afb1edc99b725c29de80f260dcf144c873bf589ae1812ef6cb05f2234\
521 f9c66c23e874a0d5d0dc52f2209e015bbcf74ee449a397f6b0318c915b7e58dea\
522 5904abbe35285e90ccf548ad1f3f52f60c3b19b3cd67644d633e68aef42d8ef17\
523 82f22a8edd0620f55f29070720ca7a078ac83e87b9ebd2783ecad17dd854ef1bb\
524 d319f1a6d3a1e4931f9097422f5a3c4af037b99e06c7610ee61102c6eea763af1\
525 08e9a16b93b2dc0891658d5c6a197df6aae9b306b2c895d21c79cb6cb6dd85b40\
526 18b0a9fe7468336e3907eb4adcaf930cacc97e8e951d2d6b25744a4143679bad1\
527 f31b210c9a2ed54b80d8f5d7dc1f1c985681534c1926920cd683d95dca7e8ea28\
528 5f9906d2e89cd8bfa76a98e38ee4b5152522d55f79610fe8d5278fe6ed5866b5d\
529 a4dcf330ea84307c34f30e1a66eb1934dafebb0074fc27c2ff73d8c0bae8416cc\
530 87bf611f81119aba9e2a911beaf3ac9507e621fc1ed1cf15dfb31408cf55e2bfd\
531 d2880db2d3489a336d6f8348347648d882f9f376331e469e809115c6cc82468f3\
532 63c910673e9ded172ded90a369e1cdd135676f623e11a1531ed221177812b1ef0\
533 c65e5ca92c0df8de7fe664710f3228a226e019c99607fe1395ecd5643e1c7ad8a\
534 132bf5131737cb970a7f0dabc00029755bf71b3f47bd69ba39b3ab104c74f0423\
535 9f4919dca1dfce7c9c41cba9d449073e106ebabe3c313b598ee8b11702ec46e9e\
536 e53fb9422f0326371898b8fa4c21a951684c687398e0bebd6f6fd91b829e8666b\
537 9a19a4273cfda0f34b8ecb902f7adc6539fb9a0cba6f87a63a957acfb2dfa1897\
538 3f4a3063668767b2be780311513c63f1814f082176f6a953f2ffaa49ec9b39fec\
539 c2eab603be7a969bb4c1dbebf8d39fa90f802d5ea52378b5025a19b64a8c2c2dd\
540 6a6133bd8d29730bd5724b5bf50c158b238d1137082937ad91a176aaf91577868\
541 db7581b457c917e612b242ce0065ad47e11dcdc1fc6158687142249bcf312497a\
542 547b6f43e795af7d4ae8cd022e44e417987e35e83de21e39dcdf86b97bd421e6e\
543 61881a432fa2284f20be80e32459443736b875d9036468ceb881589394441e2d1\
544 0aa10b6c93332951e8ba56f89fac70baf415b4511873c0f3e418ca4fe8954a28f\
545 1f7b5f590d34470119f694e2712f184882d90396c8e6aa850eaa3c2ae51990543\
546 638c46c59512167a2c5ad593532dc2142ffb6560476e4159213b9ef017ec75310\
547 d2e4624a405bb26f7192a485a94890674928c9caa4a5819ca4ddcba8fa71afc1a\
548 6baf63f039452c8fe994f8b63d58c876dfddd61a476345eaed4f66bdc0fcfc38d\
549 485c6a5b0e27d0fbc50427ff591ba38d63445c01642cfbd7d4c032f2546a6fe80\
550 bc3b598362502c552049523fe360c3bcf1cc572feb04386f97d55871dd8cea039\
551 3cdd964e724082adc98126e6f2fe1d576be4bf911e9aca70e35538175f8382bbc\
552 d614bbecc97c9607ef25da2ff08a6e5b6f76cbe9ccb0e0fdc3528e3e2c3675a5c\
553 897d295bb76524ec8a73a70b97909368f44d92f9aceaef0b03f3dafa1faa89fc6\
554 63a92da3c19b4952463fac0e825e78cf046e266cfb9975af72e9d50d2c2cafee8\
555 8fe2cecae2b1465fc07b280d83b66062dc9e7a372f81aec8e0bb9e97877814a5a\
556 6813c67746e35cd068d45d8664528bd00d5a306a5319e1bea7f38345da92d3a10\
557 d91476a26aed6b8441f0f72fbbad5d5e0f8ae5cabc9f4f08e6be7902b5c53632d\
558 b5264afee7422c87b3237a32d5213ad0eb807b61977d9d90666cbb0c70500526b\
559 0eb762c99351796db41166b0aa2f221b5607e0d629fac4e938488245c11557381\
560 a4f8addcc49913b11d42481cf8668e37bacbad4a20509e4fe4ccbcee7aea2909a\
561 2abe59052f7f28b9340cd92f69729d615b8d3b530941c0b30506498cd4e561a9c\
562 82d915266bb7115967bc76c5593c06d094bdf4294b868afc5fa52742d3bdbd593\
563 2df599f0e1187c49f0dba8679c771a514cc9da75e03506957800bf470d4a07c4b\
564 b8918d6085499bb8ceeaba23c0b465863327e9ab8b6b8cf8b3ca530ca7b02cfad\
565 f85437b750f305e8fbc8855c95bee8595a7e9e1f0993a03adbadc68665a18936c\
566 c99b6530b4518c0754990d7bfdfdac76f88cfcbcb7b3d9a71ee10cbd3a1bdbc2e\
567 50b642c1fef56511962f845bbec6eab727b1d4add335db8d80c4c07e8356ad05a\
568 dad68b012489fa5bb5d9019a667778ddf7f5edd80f1d3c4abd64397a89e554c80\
569 07809336ddc2b2e7d5219c39fdf39aad33b9350f6b18fe3b98c690b9068f36d4b\
570 7669530fd216373842fbf70fe9bbe80854b31eed4bd515d6caeb065d6c609846c\
571 9bfae1b3fce3db70b5bfb448ec69512e7f25019c789301b77a75f2a0f81c65ec2\
572 9f41bf96d597a00c310e8ba4b48ac82b5a735c1e83f22394eb2fc9b35d42a3553\
573 3c938f26290a5860175637982f1733c99be39c44ac4a09187406306bde2fd3d28\
574 e4e7bda73719912c338804dea03987757dac4d73def665e11da126f9414f71624\
575 a3b753797eb0472bd334094515c4f9fe57fdd8d185f22b4bf82e4b5f6b800870c\
576 ce19a0c8174dc11ee9f1cb9ffe0ac6f6fff1ebf7c915c7ae20172bb70390e3759\
577 912e0e0a4e83a0a2d2318f4386314a89f6438ccb331f89377ff7947fe4b24f788\
578 aef85c1656ca87ee41c959f1b09bde09f20c2a51ac481646b28e9b0fc2ff49cfe\
579 8cf28577bf5bf6f261f54f97fcd2875da4210c6dfe685450280b68e378d9a4862\
580 43cc682ed4ec747c37de1fde848e4a8f70498d22e40c462c469c884cd67330e77\
581 b694e759232313f31a1624e0e1960f23ddae47b68ff553d0de0910c8abe2e8e5f\
582 b063aa744ff77465fc731c7af79a84dcaa9b3f741a46dd3c932877d49242c6d88\
583 3e14392b8c4530986605812b636a73590ef437f27e40d1af37ed1cbd68fb4e9ca\
584 5b0b41e5daee0142c1bf59c9d71f6c19b25e6148dfbb9fb142107aabe3701e366\
585 11a7e0b13ea32d3c5f8a51f63c5f34415baa15f6ca77300eb323241ffe73c5acd\
586 97fcb682c21dc8911392979e9cb81be5218acf452b5b93f6681d323b7989fdd10\
587 efe6fe9e2ac88d0d76a4cf3ee45e3b5c430100014142c1fc7e8a658eff437594a\
588 25cf34d269556d8511918f27fdc7e9d6dd73f0e4790b91f225e9d131e6abb3dbf\
589 b66549a9aa57948fbd2f183fcd951b1d2305bffd6c0a602000000000000000016\
590 f5cdf9fb6c1b5e98a36befdc2c55bd4fd8793d554b2506f51c909362495e1216e\
591 e83cd270ddb0a00785600ba23bd3363f0798e3a7a117990415adec88e61be6517\
592 0bd587ab4d2ee38edb22a91e5c29afa397dd5a73465c51c6263f5fbde47fa801c\
593 e84464acc32589acaafadfe44d6558774b7085612a88f3424b6dca3c6f07217d1\
594 cbd5c41bda46a6a492a0119c1de4d25b58c94250bee3fba6b8223777535673a2f\
595 4da6af27598030f88144f408120f07ca9c98d5d9edcdf6cdc9073f118fce55e6c\
596 9d0be80b5e87992ddaa9c22053b3a00d42bdedc9768de25c0b37a5c4fb4e86710\
597 b33cebed5588d88adde607f6bca14f0279ce35126d403ffa50f288c87f528c197\
598 49ed43bd846c513fcd92c173fe76d8f2e69770439d3d075cb19b1094a42ee07ae\
599 1de197e8c136e2bc688a75a74db24adb0fbb73872dc80074f61c9cce9bd33861b\
600 dd921ee3edacab1d6e7cec325c172b6b6e82ada11687e4fc931225074dd1f20a0\
601 f9342dbce1fc3fdbf5bb6cb74ab6475e574e9f5f247a2f7e4fcfcc354d4da8c80\
602 66e574642c7fccbbb9ef0aa592ecab5366fe87eb8e14cd64aee34578aa48f68f8\
603 f4c5372df2c3fc429f5a3e39ef6c034c87f9c52b2ea35e28c7bf3be737c3817ef\
604 d6569466dc859e8ff8965c5249b6f045934d3d08b0ffd388aec58df8194ac2c4f\
605 ec2152942d2626595e65664b1fa33b5dae8ee796a840a56d885cbf7ae6483fad0\
606 5e507ada3f075ebce0d791b626c6dfe93f8492c4dd3b34aafc33d7644c5c8e38b\
607 fd8c19194f65be88fcb4538778632e489a626896372fdd2498b16e64daa7d3c5c\
608 fac688d6f9cdf3717261b0a1f25be1bdd6be6558ddb826fa04b5f668810a291ae\
609 a51a6f05ff7c34dcf81c74849a8015bad5e4e416989b10ef01de304775db725fa\
610 0b665f4330dc9c540dc29aab144837362a97d6bb0165cb3272338c2d32386cd95\
611 ee3e66d876b591a25a6907237523cf908f736d2fdc8e54ea8d9c7562697161d1f\
612 72fc4d7b775052415cd0e5ae5bdf6edfab5776b6ff75ce5e1f8f2beea6ec74252\
613 b63966cca58abd638279dc5c998a1068079f3e5dcc8a69165c304c3d8c362ccfa\
614 dab05ad12208a5655ab389eb727e8ed5f86b300331a13be26e2fbabf89fbfd2b9\
615 8481dd5edb52ed456a0e03a84b6f89761f91ff251412f5cfa286e35fb9f48ef0e\
616 044c4742b6e860a08767ecb80548c2f3df3b371cdb40e86dbe118f64e84faf45e\
617 cb78d73364e9e31e3412ca2a3fad0a35983370ea9e6264a222edd1fd4aca30e3c\
618 169d7ca2d07609262e786ecd019c1417a06b7dfa32a54e0897afdc6492f266115\
619 55cbff47dba3b76381f239d597a8f687669333e0b47b53d5bcc4fea1919490bad\
620 3c6f0b6a58a50aca7ddeb9745ead454e0a38d9486fb52aefe0dbb92bf7fd6c215\
621 078aba3482b11274ec8cddff92c359bbc6d20bd823ad0bbf859cfaadf8e775b3d\
622 37b3078319f46c6d2a112cf60a673fee467538c70f1687d97fbe9d9f8a0856061\
623 592a4e00b6d10e979e674dd2cd0ba8b853f733877cd508062d5f723d58d215ad6\
624 9c2be6be742496aef54eb87338622eb36a9bbc5a7a602d280a45e095b1e078dab\
625 54479e783a513c722066acaae44ccc15f9560da91ed053ec05c36d82f68097668\
626 76c45c4fbeb2321d50f48f7995437d0c5fc365974a571fb0352d28cb1cdbd21d6\
627 9fab576a2e68d6b881776027bcdb7f01be22b1c847d91f26e680ef6ab2c128a89\
628 b59432383d9bd661b0b01432cf8a25319426d38ac2e2114825f59b4250569c798\
629 b1094920bb31130728313ff56a6eef2e6c4b275215dce3786d0f9024952b5f572\
630 566c53597e7ef4ab1f75743e605a564054d667f48906b5481d924769ef65751e3\
631 49891d725a2c1bf8b102fea4c25c874d2fc2ce1bfec4b39bea76fbf7a28855725\
632 d52b595a4fc96892c3f1f961d46310ebd5221df729c02060035c559baf0fd7efa\
633 73a2213ca29642857aeb8ebf7efdf9d2f5c84746b6fc35ab355a8dca56e7dde48\
634 31e47ca1be6b62af30cfcf807c384e56ab84ff03bbe786251e6c4b932c9217bf6\
635 71046217bd0511fdc06aa69050c1480281e4843eb73d80095a2fb8e68a2c0c98c\
636 9aea637b99d87ad847a3a76d59ea308c751f9cb4a4fce2989822bd6ba2f901f09\
637 df647536dc30730ea3160dd35b8c6dcc9aa815b79ed492a8a299a298ccdf784b9\
638 b0211ca877ec1723817c98529acaa4d3727162b5740b0fc9b498dfb2212a3cbf0\
639 c63dc4f7663fafad7905643a792862b651e8497b0f0da632b897ecf9ee63f2b20\
640 b54fa5eb2f2e424dcce5a075f50b856af266655be3a815fc83ed8027508b25369\
641 76982196b160e2219ffdb5c7a56dd3e6b700860c711f4439dbf72973f4f26fe32\
642 60ec43a3446fe14444b9787d877e107be610147eec4a3574745e95a1f424aff06\
643 2f84c559d13b1e6b59e8dc2221515c229f07db8eb39c515a321d8bd07b1bd6c9a\
644 79dac6d951c04415553c7a2ce1eb77495c7f89c4d5b4cffd289435b69bc535850\
645 95083cc5a1b191781342266e204e1566aca8175e2ae84a8bd711d188b666dfb65\
646 a6442776d3e23c1b5192af09ec712537f2157d0ccbc1bb3b3a1969d9705671f16\
647 bdc266e615ad2e50a8cbd666f3ee7465cc430c6cd69d30c91e717b12f7094b6f0\
648 ef89134d6c1620d28d8f238c181146448b348e4ca2e93c737210350f18fb878fb\
649 91b70ecc5689e5b6101ecfc545f6a1c903115b0c6419c91a50fb2dbe2edd362f2\
650 815f0c75070974507c34130ac9b29747ff7efbe6e37ee4c62be3ecfedfa817fdf\
651 3309163aaff677775b77f0d288c9858cfe59cb0fa18afa591e7d574eaef43c82e\
652 79d71542c4177de4e5bd724b18cfd33c68530665728a9d5ef192772094acbf3d8\
653 85d5146c1634e74754e3fbcb94fa349eac8280cfd7d1f46a0813b57a83bd078b1\
654 f7cb5a60a59b59380fe04e1c600c33b33d1add69a9ff1be546f0ec5c0083979fc\
655 e940b23711f382ac0d011c1103f02cb6082c18e39cf7a9c3bf4c081f905ae7b87\
656 951a7880b57e934465ccd634e5a17fd8d8866abfdfebd33b2c3d2c5be58144900\
657 c04e9c18de0c80270660e62a3c185277555f89da4c41bd33cec1359f4ed21abdb\
658 586e1d97f720a92d16014d7f1822f1836f74c97cb7f7b38e073477c6ab064fde8\
659 35916c1e624de81f2ad90f6260073c5e1848582860f033630bde225821b39c257\
660 2b30c36adf8fdb8317c33df05f6413447f4985d12e9012629df09dc8f43373a6d\
661 0db4b0048453a6f1ec662472c77a30d5cf4ac7084f736d0d598c251f2aefc9860\
662 52fbf12a657885d7140ad36b07c63ab86388a2be12d943747f3f29ef9f2e11e14\
663 44cc873df0ed7826eef675389a0d5a0388a8504fe89c4791ea4a572bfd406d5f0\
664 1418b4f888c9a7a566e32811936bf6950bbf786b86c41c28f2045d31953fcd15f\
665 179e7bc00c72870890537921f7deff82270b0e44b88720aa738f60a85567deb7c\
666 90b0c2444467621e53e1c079436d31d3d0b34dd237fc281eb9d87175237a9a433\
667 142db4bb7f8c4cb6a34e2dc73f074045d216695ce88ef68e18564c935c9cbd902\
668 e939655c258de2ab78def8746bffd972083afce3b6881b7147262e1a44e022468\
669 9fafa1a3cb823c8da6eb7df091bec0638bf728b7b10aa95f2bce512ec8d325293\
670 8d2eb77b44ace7a2f976588032cac5af670f9e5ca25cb0721bc1baec26f9c3a9f\
671 41b02fb62997d6cb0a01314845e9d0e78139ea49f2ead8736e0000"
672 );
673
674 assert_eq!(
675 block.block_hash().to_string(),
676 "e935d06cf3a616eb4d551338598b84daa0e8592ed14673263597f6af4b4a6ea6"
677 );
678 assert_eq!(block.header.version, 0x2000_0000);
679 assert_eq!(block.header.height, 1);
680 assert_eq!(block.txdata.len(), 3);
681 assert_eq!(block.size(), serialize(&block).len());
682
683 let block: Block = hex_deserialize!(
685 "0000002069de100c1bae40e1cf8819bd18282e4ca370f62123c8ea2c60836984\
686 ba052270ee0cb6e5458591ac157ad414a111db4d34cedffc22e096291f7b4b3c\
687 8de3f69f8d53815b03000000695221031c25c60ef342990d9bf75425c1dc2392\
688 b5e206268d9d35044b731735db230c38210319c5a32a8ae698aaf1246784f542\
689 31d8d20f81b91c31353214538b827d718c8d210399d55e0a7fb30281da074dfb\
690 bb2654cacc2d03289ba79feae702ad6dbb542aab53ae9000463044022029bbe1\
691 79c2f0d8e6d1576869cea19ef439d0e52373f7efab77cd6ccb551b29f6022042\
692 baa3c17fccfb265ee878059b6cb85d40b976a30495c6ca14b7ffe6d1d8757247\
693 3045022100da88bb6fa1ecf3060ad7c8347eaa1a7ef8c9ae27a8b0136cff9099\
694 94ca409f9e022068ddf3090bde1e04deda04f762eb35858d7dfc17e156bfc1c8\
695 131ca07a349dda01020000000101000000000000000000000000000000000000\
696 0000000000000000000000000000ffffffff03530101ffffffff02018dc25a05\
697 5e773e7e91d4678053ebc702cce47f07b29f3ebd7c4b34cd30fb240201000000\
698 000000000000016a018dc25a055e773e7e91d4678053ebc702cce47f07b29f3e\
699 bd7c4b34cd30fb240201000000000000000000266a24aa21a9ed94f15ed3a621\
700 65e4a0b99699cc28b48e19cb5bc1b1f47155db62d63f1e047d45000000000000\
701 0120000000000000000000000000000000000000000000000000000000000000\
702 00000000000000"
703 );
704
705 assert_eq!(
706 block.block_hash().to_string(),
707 "bcc6eb2ab6c97b9b4590825b9136f100b22e090c0469818572b8b93926a79f28"
708 );
709 assert_eq!(block.header.version, 0x2000_0000);
710 if let ExtData::Proof { challenge, solution } = block.header.ext {
711 assert_eq!(challenge.len(), 1 + 3 * 34 + 2);
712 assert_eq!(solution.len(), 144);
713 } else {
714 panic!("dynafed test vector was parsed as non-dynafed");
715 }
716 }
717
718 #[test]
719 fn dynafed_block() {
720 let block: Block = hex_deserialize!(DYNAFED_BLOCK);
722
723 if let ExtData::Dynafed { current, proposed, .. } = block.clone().header.ext {
725 if let dynafed::Params::Compact { signblock_witness_limit, .. } = current {
726 assert_eq!(signblock_witness_limit, 258);
727 } else {
728 panic!("Current block dynafed params not compact");
729 }
730 if let dynafed::Params::Null = proposed {
731 } else {
733 panic!("Proposed block dynafed params not compact");
734 }
735 } else {
736 panic!("No dynafed params");
737 }
738
739 assert_eq!(
740 block.block_hash().to_string(),
741 "4961df970cf12d789383974e6ab439f780d956b5a50162ca9d281362e46c605a"
742 );
743 assert_eq!(block.header.version, 0x2000_0000);
744
745 let block: Block = hex_deserialize!("\
747 000000a01ecf88cda4d9e6339109c685417c526e8316fe0d3ea058765634dcbb\
748 205d3081bd83073b1f1793154ab820c70a1fda32a0d45bb0e1f40c0c61ae0350\
749 7f49c293debcc45d1400000002220020a6794de47a1612cc94c1b978d5bd1b25\
750 873f4cab0b1a76260b0b8af9ad954dc74b0100002200204ae81572f06e1b88fd\
751 5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260015100022200204cb4\
752 0d59d6e1bbe963f3a63021b0d7d5474b87206978a1129fbffc4d1c1cf7e44b01\
753 00002200204ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c0\
754 0b8cc332600151000500483045022100ab2203a8a68d7eca8a3a0fac91e7c780\
755 2656d937535800da82f7102e1c06f7b80220576f004cb14b95178c71e36bf947\
756 bfea496b00b66c18d2eb8febf46362d50e2b0147304402202d4630887d661a50\
757 b76b7b32555fd76906ad298ce24483df42310ffbf62d451802200e0d64069e58\
758 047c271c1b4051c1ff3d1cba7d32e56abb0d8b8bc30e1bed075b014830450221\
759 00c6b196967c661c4543802a895ae731af44862e75d9e3c65b8efdd668727a34\
760 af022041ff4d67029052eb6305d25d0fc4813d21a939ff5316a12562d0c90389\
761 76f8e1016953210296db75c11ea3a292a372f6c94f5013eaeb379f701857a702\
762 f3b83f88da21be6f21021f0d8638c413ef7769cd711ce84c8f192f5a85f0fd6d\
763 8e63ddb4d2cf6740b23b2103cadff18e928133df2e670a3715c4e7a81d357de3\
764 6ddaa5016628e70a3e6a452f53ae010200000001010000000000000000000000\
765 000000000000000000000000000000000000000000ffffffff0401140101ffff\
766 ffff020137c495f58d698979ff9124e8c7455fe79b13ddb96afa25c45894eb05\
767 9868a8c001000000000000000000016a0137c495f58d698979ff9124e8c7455f\
768 e79b13ddb96afa25c45894eb059868a8c001000000000000000000266a24aa21\
769 a9ed94f15ed3a62165e4a0b99699cc28b48e19cb5bc1b1f47155db62d63f1e04\
770 7d45000000000000012000000000000000000000000000000000000000000000\
771 000000000000000000000000000000\
772 ");
773
774 if let ExtData::Dynafed { current, proposed, .. } = block.clone().header.ext {
776 if let dynafed::Params::Full { .. } = current {
777 } else {
779 panic!("Current block dynafed params not full");
780 }
781 if let dynafed::Params::Full { .. } = proposed {
782 } else {
784 panic!("Proposed block dynafed params not full");
785 }
786 } else {
787 panic!("No dynafed params");
788 }
789 assert_eq!(
790 block.block_hash().to_string(),
791 "e9a5176b1690a448f76fb691ab4d516e60e13a6e7a49454c62dbf0d611ffcce7"
792 );
793 }
794
795 #[test]
796 fn test_failed_block() {
797 let block_str = include_str!("../tests/data/failedblock.hex");
798
799 let bytes = Vec::<u8>::from_hex(block_str).unwrap();
800 let _block = encode::deserialize::<Block>(&bytes).unwrap();
801 }
802}