tests for block hash, .editorconfig and bitcoin network enum

This commit is contained in:
debris 2016-08-16 14:32:24 +02:00
parent 03c3f97276
commit 853bf87a10
4 changed files with 76 additions and 2 deletions

16
.editorconfig Normal file
View File

@ -0,0 +1,16 @@
root = true
[*]
indent_style=tab
indent_size=tab
tab_width=4
end_of_line=lf
charset=utf-8
trim_trailing_whitespace=true
max_line_length=120
insert_final_newline=true
[.travis.yml]
indent_style=space
indent_size=2
tab_width=8
end_of_line=lf

View File

@ -1,9 +1,10 @@
use block_header::BlockHeader;
use compact_integer::CompactInteger;
use crypto::dhash;
use hash::H256;
use merkle_root::merkle_root;
use reader::{Deserializable, Reader, Error as ReaderError};
use stream::{Serializable, Stream};
use stream::{Serializable, Stream, serialize};
use transaction::Transaction;
pub struct Block {
@ -36,6 +37,10 @@ impl Deserializable for Block {
}
impl Block {
pub fn hash(&self) -> H256 {
dhash(&serialize(&self.block_header))
}
/// Returns block's merkle root.
pub fn merkle_root(&self) -> H256 {
let hashes = self.transactions.iter().map(Transaction::hash).collect::<Vec<H256>>();
@ -53,11 +58,14 @@ mod tests {
// https://blockchain.info/rawblock/000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6
// https://blockchain.info/rawblock/000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6?format=hex
#[test]
fn test_block_merkle_root() {
fn test_block_merkle_root_and_hash() {
let encoded_block = "01000000ba8b9cda965dd8e536670f9ddec10e53aab14b20bacad27b9137190000000000190760b278fe7b8565fda3b968b918d5fd997f993b23674c0af3b6fde300b38f33a5914ce6ed5b1b01e32f570201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704e6ed5b1b014effffffff0100f2052a01000000434104b68a50eaa0287eff855189f949c1c6e5f58b37c88231373d8a59809cbae83059cc6469d65c665ccfd1cfeb75c6e8e19413bba7fbff9bc762419a76d87b16086eac000000000100000001a6b97044d03da79c005b20ea9c0e1a6d9dc12d9f7b91a5911c9030a439eed8f5000000004948304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446618c4571d1090db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fdd7d5d6cc8d25c6b241501ffffffff0100f2052a010000001976a914404371705fa9bd789a2fcd52d2c580b65d35549d88ac00000000".from_hex().unwrap();
let mut merkle_root = "8fb300e3fdb6f30a4c67233b997f99fdd518b968b9a3fd65857bfe78b2600719".from_hex().unwrap();
let mut hash = "000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6".from_hex().unwrap();
merkle_root.reverse();
hash.reverse();
let block: Block = deserialize(&encoded_block).unwrap();
assert_eq!(block.merkle_root().to_vec(), merkle_root);
assert_eq!(block.hash().to_vec(), hash);
}
}

View File

@ -10,6 +10,7 @@ pub mod compact_integer;
pub mod crypto;
pub mod hash;
pub mod merkle_root;
pub mod network;
pub mod reader;
pub mod stream;
pub mod transaction;

49
src/network.rs Normal file
View File

@ -0,0 +1,49 @@
//! Bitcoin network
const MAGIC_MAINNET: u32 = 0xD9B4BEF9;
const MAGIC_TESTNET: u32 = 0x0709110B;
/// Bitcoin network
/// https://bitcoin.org/en/glossary/mainnet
#[derive(Debug, PartialEq)]
pub enum Network {
/// The original and main network for Bitcoin transactions, where satoshis have real economic value.
Mainnet,
Testnet,
}
#[derive(Debug, PartialEq)]
pub struct FromMagicError;
impl Network {
/// Magic number
/// https://www.anintegratedworld.com/unravelling-the-mysterious-block-chain-magic-number/
pub fn magic(&self) -> u32 {
match *self {
Network::Mainnet => MAGIC_MAINNET,
Network::Testnet => MAGIC_TESTNET,
}
}
pub fn from_magic(magic: u32) -> Result<Self, FromMagicError> {
match magic {
MAGIC_MAINNET => Ok(Network::Mainnet),
MAGIC_TESTNET => Ok(Network::Testnet),
_ => Err(FromMagicError),
}
}
}
#[cfg(test)]
mod tests {
use super::{Network, MAGIC_MAINNET, MAGIC_TESTNET, FromMagicError};
#[test]
fn test_network_magic_number() {
assert_eq!(Network::Mainnet.magic(), MAGIC_MAINNET);
assert_eq!(Network::Testnet.magic(), MAGIC_TESTNET);
assert_eq!(Network::from_magic(MAGIC_MAINNET).unwrap(), Network::Mainnet);
assert_eq!(Network::from_magic(MAGIC_TESTNET).unwrap(), Network::Testnet);
assert_eq!(Network::from_magic(0).unwrap_err(), FromMagicError);
}
}