1use prelude::*;
24
25use core::fmt;
26
27use util;
28use util::Error::{BlockBadTarget, BlockBadProofOfWork};
29use util::hash::bitcoin_merkle_root;
30use hashes::{Hash, HashEngine};
31use hash_types::{Wtxid, BlockHash, TxMerkleNode, WitnessMerkleNode, WitnessCommitment};
32use util::uint::Uint256;
33use consensus::encode::Encodable;
34use network::constants::Network;
35use blockdata::transaction::Transaction;
36use blockdata::constants::{max_target, WITNESS_SCALE_FACTOR};
37use blockdata::script;
38use VarInt;
39
40#[derive(Copy, PartialEq, Eq, Clone, Debug)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44pub struct BlockHeader {
45 pub version: i32,
47 pub prev_blockhash: BlockHash,
49 pub merkle_root: TxMerkleNode,
51 pub time: u32,
53 pub bits: u32,
56 pub nonce: u32,
58}
59
60impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
61
62impl BlockHeader {
63 pub fn block_hash(&self) -> BlockHash {
65 let mut engine = BlockHash::engine();
66 self.consensus_encode(&mut engine).expect("engines don't error");
67 BlockHash::from_engine(engine)
68 }
69
70 pub fn target(&self) -> Uint256 {
72 Self::u256_from_compact_target(self.bits)
73 }
74
75 pub fn u256_from_compact_target(bits: u32) -> Uint256 {
89 let (mant, expt) = {
94 let unshifted_expt = bits >> 24;
95 if unshifted_expt <= 3 {
96 ((bits & 0xFFFFFF) >> (8 * (3 - unshifted_expt as usize)), 0)
97 } else {
98 (bits & 0xFFFFFF, 8 * ((bits >> 24) - 3))
99 }
100 };
101
102 if mant > 0x7FFFFF {
104 Default::default()
105 } else {
106 Uint256::from_u64(mant as u64).unwrap() << (expt as usize)
107 }
108 }
109
110 pub fn compact_target_from_u256(value: &Uint256) -> u32 {
112 let mut size = (value.bits() + 7) / 8;
113 let mut compact = if size <= 3 {
114 (value.low_u64() << (8 * (3 - size))) as u32
115 } else {
116 let bn = *value >> (8 * (size - 3));
117 bn.low_u32()
118 };
119
120 if (compact & 0x00800000) != 0 {
121 compact >>= 8;
122 size += 1;
123 }
124
125 compact | (size << 24) as u32
126 }
127
128 pub fn difficulty(&self, network: Network) -> u64 {
130 (max_target(network) / self.target()).low_u64()
131 }
132
133 pub fn validate_pow(&self, required_target: &Uint256) -> Result<BlockHash, util::Error> {
135 let target = &self.target();
136 if target != required_target {
137 return Err(BlockBadTarget);
138 }
139 let block_hash = self.block_hash();
140 let mut ret = [0u64; 4];
141 util::endian::bytes_to_u64_slice_le(block_hash.as_inner(), &mut ret);
142 let hash = &Uint256(ret);
143 if hash <= target { Ok(block_hash) } else { Err(BlockBadProofOfWork) }
144 }
145
146 pub fn work(&self) -> Uint256 {
148 let mut ret = !self.target();
150 let mut ret1 = self.target();
151 ret1.increment();
152 ret = ret / ret1;
153 ret.increment();
154 ret
155 }
156}
157
158#[derive(PartialEq, Eq, Clone, Debug)]
161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
162pub struct Block {
163 pub header: BlockHeader,
165 pub txdata: Vec<Transaction>
167}
168
169impl_consensus_encoding!(Block, header, txdata);
170
171impl Block {
172 pub fn block_hash(&self) -> BlockHash {
174 self.header.block_hash()
175 }
176
177 pub fn check_merkle_root(&self) -> bool {
179 match self.compute_merkle_root() {
180 Some(merkle_root) => self.header.merkle_root == merkle_root,
181 None => false,
182 }
183 }
184
185 pub fn check_witness_commitment(&self) -> bool {
187 const MAGIC: [u8; 6] = [0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed];
188 if self.txdata.iter().all(|t| t.input.iter().all(|i| i.witness.is_empty())) {
190 return true;
191 }
192
193 if self.txdata.is_empty() {
194 return false;
195 }
196
197 let coinbase = &self.txdata[0];
198 if !coinbase.is_coin_base() {
199 return false;
200 }
201
202 if let Some(pos) = coinbase.output.iter()
204 .rposition(|o| o.script_pubkey.len () >= 38 && o.script_pubkey[0..6] == MAGIC)
205 {
206 let commitment = WitnessCommitment::from_slice(&coinbase.output[pos].script_pubkey.as_bytes()[6..38]).unwrap();
207 let witness_vec: Vec<_> = coinbase.input[0].witness.iter().collect();
209 if witness_vec.len() == 1 && witness_vec[0].len() == 32 {
210 if let Some(witness_root) = self.witness_root() {
211 return commitment == Self::compute_witness_commitment(&witness_root, witness_vec[0]);
212 }
213 }
214 }
215
216 false
217 }
218
219 pub fn compute_merkle_root(&self) -> Option<TxMerkleNode> {
221 let hashes = self.txdata.iter().map(|obj| obj.txid().as_hash());
222 bitcoin_merkle_root(hashes).map(|h| h.into())
223 }
224
225 #[deprecated(since = "0.28.0", note = "Please use `block::compute_merkle_root` instead.")]
227 pub fn merkle_root(&self) -> Option<TxMerkleNode> {
228 self.compute_merkle_root()
229 }
230
231 pub fn compute_witness_commitment(witness_root: &WitnessMerkleNode, witness_reserved_value: &[u8]) -> WitnessCommitment {
233 let mut encoder = WitnessCommitment::engine();
234 witness_root.consensus_encode(&mut encoder).expect("engines don't error");
235 encoder.input(witness_reserved_value);
236 WitnessCommitment::from_engine(encoder)
237 }
238
239 pub fn witness_root(&self) -> Option<WitnessMerkleNode> {
241 let hashes = self.txdata.iter().enumerate().map(|(i, t)| {
242 if i == 0 {
243 Wtxid::default().as_hash()
245 } else {
246 t.wtxid().as_hash()
247 }
248 });
249 bitcoin_merkle_root(hashes).map(|h| h.into())
250 }
251
252 fn base_size(&self) -> usize {
254 80 + VarInt(self.txdata.len() as u64).len()
255 }
256
257 #[deprecated(since = "0.28.0", note = "Please use `block::size` instead.")]
259 pub fn get_size(&self) -> usize {
260 self.size()
261 }
262
263 pub fn size(&self) -> usize {
267 let txs_size: usize = self.txdata.iter().map(Transaction::size).sum();
268 self.base_size() + txs_size
269 }
270
271 #[deprecated(since = "0.28.0", note = "Please use `transaction::strippedsize` instead.")]
273 pub fn get_strippedsize(&self) -> usize {
274 self.strippedsize()
275 }
276
277 pub fn strippedsize(&self) -> usize {
279 let txs_size: usize = self.txdata.iter().map(Transaction::strippedsize).sum();
280 self.base_size() + txs_size
281 }
282
283 #[deprecated(since = "0.28.0", note = "Please use `transaction::weight` instead.")]
285 pub fn get_weight(&self) -> usize {
286 self.weight()
287 }
288
289 pub fn weight(&self) -> usize {
291 let base_weight = WITNESS_SCALE_FACTOR * self.base_size();
292 let txs_weight: usize = self.txdata.iter().map(Transaction::weight).sum();
293 base_weight + txs_weight
294 }
295
296 pub fn coinbase(&self) -> Option<&Transaction> {
298 self.txdata.first()
299 }
300
301 pub fn bip34_block_height(&self) -> Result<u64, Bip34Error> {
303 if self.header.version < 2 {
313 return Err(Bip34Error::Unsupported);
314 }
315
316 let cb = self.coinbase().ok_or(Bip34Error::NotPresent)?;
317 let input = cb.input.first().ok_or(Bip34Error::NotPresent)?;
318 let push = input.script_sig.instructions_minimal().next().ok_or(Bip34Error::NotPresent)?;
319 match push.map_err(|_| Bip34Error::NotPresent)? {
320 script::Instruction::PushBytes(b) if b.len() <= 8 => {
321 let mut full = [0; 8];
323 full[0..b.len()].copy_from_slice(b);
324 Ok(util::endian::slice_to_u64_le(&full))
325 }
326 script::Instruction::PushBytes(b) if b.len() > 8 => {
327 Err(Bip34Error::UnexpectedPush(b.to_vec()))
328 }
329 _ => Err(Bip34Error::NotPresent),
330 }
331 }
332}
333
334#[derive(Debug, Clone, PartialEq, Eq)]
336pub enum Bip34Error {
337 Unsupported,
339 NotPresent,
341 UnexpectedPush(Vec<u8>),
343}
344
345impl fmt::Display for Bip34Error {
346 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
347 match *self {
348 Bip34Error::Unsupported => write!(f, "block doesn't support BIP34"),
349 Bip34Error::NotPresent => write!(f, "BIP34 push not present in block's coinbase"),
350 Bip34Error::UnexpectedPush(ref p) => {
351 write!(f, "unexpected byte push of > 8 bytes: {:?}", p)
352 }
353 }
354 }
355}
356
357#[cfg(feature = "std")]
358impl ::std::error::Error for Bip34Error {}
359
360#[cfg(test)]
361mod tests {
362 use hashes::hex::FromHex;
363
364 use blockdata::block::{Block, BlockHeader};
365 use consensus::encode::{deserialize, serialize};
366 use util::uint::Uint256;
367 use util::Error::{BlockBadTarget, BlockBadProofOfWork};
368 use network::constants::Network;
369
370 #[test]
371 fn test_coinbase_and_bip34() {
372 let block_hex = "0200000035ab154183570282ce9afc0b494c9fc6a3cfea05aa8c1add2ecc56490000000038ba3d78e4500a5a7570dbe61960398add4410d278b21cd9708e6d9743f374d544fc055227f1001c29c1ea3b0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3703a08601000427f1001c046a510100522cfabe6d6d0000000000000000000068692066726f6d20706f6f6c7365727665726aac1eeeed88ffffffff0100f2052a010000001976a914912e2b234f941f30b18afbb4fa46171214bf66c888ac00000000";
374 let block: Block = deserialize(&Vec::<u8>::from_hex(block_hex).unwrap()).unwrap();
375
376 let cb_txid = "d574f343976d8e70d91cb278d21044dd8a396019e6db70755a0a50e4783dba38";
377 assert_eq!(block.coinbase().unwrap().txid().to_string(), cb_txid);
378
379 assert_eq!(block.bip34_block_height(), Ok(100_000));
380
381
382 let bad_hex = "0200000035ab154183570282ce9afc0b494c9fc6a3cfea05aa8c1add2ecc56490000000038ba3d78e4500a5a7570dbe61960398add4410d278b21cd9708e6d9743f374d544fc055227f1001c29c1ea3b0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3d09a08601112233445566000427f1001c046a510100522cfabe6d6d0000000000000000000068692066726f6d20706f6f6c7365727665726aac1eeeed88ffffffff0100f2052a010000001976a914912e2b234f941f30b18afbb4fa46171214bf66c888ac00000000";
384 let bad: Block = deserialize(&Vec::<u8>::from_hex(bad_hex).unwrap()).unwrap();
385
386 let push = Vec::<u8>::from_hex("a08601112233445566").unwrap();
387 assert_eq!(bad.bip34_block_height(), Err(super::Bip34Error::UnexpectedPush(push)));
388 }
389
390 #[test]
391 fn block_test() {
392 let some_block = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d026e04ffffffff0100f2052a0100000043410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac00000000010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000").unwrap();
394 let cutoff_block = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d026e04ffffffff0100f2052a0100000043410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac00000000010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac").unwrap();
395
396 let prevhash = Vec::from_hex("4ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000").unwrap();
397 let merkle = Vec::from_hex("bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914c").unwrap();
398 let work = Uint256([0x100010001u64, 0, 0, 0]);
399
400 let decode: Result<Block, _> = deserialize(&some_block);
401 let bad_decode: Result<Block, _> = deserialize(&cutoff_block);
402
403 assert!(decode.is_ok());
404 assert!(bad_decode.is_err());
405 let real_decode = decode.unwrap();
406 assert_eq!(real_decode.header.version, 1);
407 assert_eq!(serialize(&real_decode.header.prev_blockhash), prevhash);
408 assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
409 assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
410 assert_eq!(real_decode.header.time, 1231965655);
411 assert_eq!(real_decode.header.bits, 486604799);
412 assert_eq!(real_decode.header.nonce, 2067413810);
413 assert_eq!(real_decode.header.work(), work);
414 assert_eq!(real_decode.header.validate_pow(&real_decode.header.target()).unwrap(), real_decode.block_hash());
415 assert_eq!(real_decode.header.difficulty(Network::Bitcoin), 1);
416 assert_eq!(real_decode.size(), some_block.len());
419 assert_eq!(real_decode.strippedsize(), some_block.len());
420 assert_eq!(real_decode.weight(), some_block.len() * 4);
421
422 assert!(real_decode.check_witness_commitment());
424
425 assert_eq!(serialize(&real_decode), some_block);
426 }
427
428 #[test]
430 fn segwit_block_test() {
431 let segwit_block = include_bytes!("../../test_data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw").to_vec();
432
433 let decode: Result<Block, _> = deserialize(&segwit_block);
434
435 let prevhash = Vec::from_hex("2aa2f2ca794ccbd40c16e2f3333f6b8b683f9e7179b2c4d74906000000000000").unwrap();
436 let merkle = Vec::from_hex("10bc26e70a2f672ad420a6153dd0c28b40a6002c55531bfc99bf8994a8e8f67e").unwrap();
437 let work = Uint256([0x257c3becdacc64u64, 0, 0, 0]);
438
439 assert!(decode.is_ok());
440 let real_decode = decode.unwrap();
441 assert_eq!(real_decode.header.version, 0x20000000); assert_eq!(serialize(&real_decode.header.prev_blockhash), prevhash);
443 assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
444 assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
445 assert_eq!(real_decode.header.time, 1472004949);
446 assert_eq!(real_decode.header.bits, 0x1a06d450);
447 assert_eq!(real_decode.header.nonce, 1879759182);
448 assert_eq!(real_decode.header.work(), work);
449 assert_eq!(real_decode.header.validate_pow(&real_decode.header.target()).unwrap(), real_decode.block_hash());
450 assert_eq!(real_decode.header.difficulty(Network::Testnet), 2456598);
451 assert_eq!(real_decode.size(), segwit_block.len());
454 assert_eq!(real_decode.strippedsize(), 4283);
455 assert_eq!(real_decode.weight(), 17168);
456
457 assert!(real_decode.check_witness_commitment());
458
459 assert_eq!(serialize(&real_decode), segwit_block);
460 }
461
462 #[test]
463 fn block_version_test() {
464 let block = Vec::from_hex("ffffff7f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
465 let decode: Result<Block, _> = deserialize(&block);
466 assert!(decode.is_ok());
467 let real_decode = decode.unwrap();
468 assert_eq!(real_decode.header.version, 2147483647);
469
470 let block2 = Vec::from_hex("000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
471 let decode2: Result<Block, _> = deserialize(&block2);
472 assert!(decode2.is_ok());
473 let real_decode2 = decode2.unwrap();
474 assert_eq!(real_decode2.header.version, -2147483648);
475 }
476
477 #[test]
478 fn validate_pow_test() {
479 let some_header = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap();
480 let some_header: BlockHeader = deserialize(&some_header).expect("Can't deserialize correct block header");
481 assert_eq!(some_header.validate_pow(&some_header.target()).unwrap(), some_header.block_hash());
482
483 match some_header.validate_pow(&Uint256::default()) {
485 Err(BlockBadTarget) => (),
486 _ => assert!(false)
487 }
488
489 let mut invalid_header: BlockHeader = some_header.clone();
491 invalid_header.version = invalid_header.version + 1;
492 match invalid_header.validate_pow(&invalid_header.target()) {
493 Err(BlockBadProofOfWork) => (),
494 _ => assert!(false)
495 }
496 }
497
498 #[test]
499 fn compact_roundrtip_test() {
500 let some_header = Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap();
501
502 let header: BlockHeader = deserialize(&some_header).expect("Can't deserialize correct block header");
503
504 assert_eq!(header.bits, BlockHeader::compact_target_from_u256(&header.target()));
505 }
506}
507
508#[cfg(all(test, feature = "unstable"))]
509mod benches {
510 use super::Block;
511 use EmptyWrite;
512 use consensus::{deserialize, Encodable};
513 use test::{black_box, Bencher};
514 use network::stream_reader::StreamReader;
515
516 #[bench]
517 #[allow(deprecated)]
518 pub fn bench_stream_reader(bh: &mut Bencher) {
519 let big_block = include_bytes!("../../test_data/mainnet_block_000000000000000000000c835b2adcaedc20fdf6ee440009c249452c726dafae.raw");
520 assert_eq!(big_block.len(), 1_381_836);
521 let big_block = black_box(big_block);
522
523 bh.iter(|| {
524 let mut reader = StreamReader::new(&big_block[..], None);
525 let block: Block = reader.read_next().unwrap();
526 black_box(&block);
527 });
528 }
529
530 #[bench]
531 pub fn bench_block_serialize(bh: &mut Bencher) {
532 let raw_block = include_bytes!("../../test_data/mainnet_block_000000000000000000000c835b2adcaedc20fdf6ee440009c249452c726dafae.raw");
533
534 let block: Block = deserialize(&raw_block[..]).unwrap();
535
536 let mut data = Vec::with_capacity(raw_block.len());
537
538 bh.iter(|| {
539 let result = block.consensus_encode(&mut data);
540 black_box(&result);
541 data.clear();
542 });
543 }
544
545 #[bench]
546 pub fn bench_block_serialize_logic(bh: &mut Bencher) {
547 let raw_block = include_bytes!("../../test_data/mainnet_block_000000000000000000000c835b2adcaedc20fdf6ee440009c249452c726dafae.raw");
548
549 let block: Block = deserialize(&raw_block[..]).unwrap();
550
551 bh.iter(|| {
552 let size = block.consensus_encode(&mut EmptyWrite);
553 black_box(&size);
554 });
555 }
556
557 #[bench]
558 pub fn bench_block_deserialize(bh: &mut Bencher) {
559 let raw_block = include_bytes!("../../test_data/mainnet_block_000000000000000000000c835b2adcaedc20fdf6ee440009c249452c726dafae.raw");
560
561 bh.iter(|| {
562 let block: Block = deserialize(&raw_block[..]).unwrap();
563 black_box(&block);
564 });
565 }
566}