Compute and store BlockHash inside BlockHeader
This commit is contained in:
parent
b66ac11775
commit
a3b85b8fe6
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use hex;
|
use hex;
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -22,13 +23,16 @@ impl fmt::Display for BlockHash {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Zcash block header.
|
/// A Zcash block header.
|
||||||
pub struct BlockHeader(BlockHeaderData);
|
pub struct BlockHeader {
|
||||||
|
hash: BlockHash,
|
||||||
|
data: BlockHeaderData,
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for BlockHeader {
|
impl Deref for BlockHeader {
|
||||||
type Target = BlockHeaderData;
|
type Target = BlockHeaderData;
|
||||||
|
|
||||||
fn deref(&self) -> &BlockHeaderData {
|
fn deref(&self) -> &BlockHeaderData {
|
||||||
&self.0
|
&self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +48,31 @@ pub struct BlockHeaderData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockHeaderData {
|
impl BlockHeaderData {
|
||||||
pub fn freeze(self) -> BlockHeader {
|
pub fn freeze(self) -> io::Result<BlockHeader> {
|
||||||
BlockHeader(self)
|
BlockHeader::from_data(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockHeader {
|
impl BlockHeader {
|
||||||
|
fn from_data(data: BlockHeaderData) -> io::Result<Self> {
|
||||||
|
let mut header = BlockHeader {
|
||||||
|
hash: BlockHash([0; 32]),
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
let mut raw = vec![];
|
||||||
|
header.write(&mut raw)?;
|
||||||
|
header
|
||||||
|
.hash
|
||||||
|
.0
|
||||||
|
.copy_from_slice(&Sha256::digest(&Sha256::digest(&raw)));
|
||||||
|
Ok(header)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the hash of this header.
|
||||||
|
pub fn hash(&self) -> BlockHash {
|
||||||
|
self.hash
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
||||||
let version = reader.read_i32::<LittleEndian>()?;
|
let version = reader.read_i32::<LittleEndian>()?;
|
||||||
|
|
||||||
|
@ -70,7 +93,7 @@ impl BlockHeader {
|
||||||
|
|
||||||
let solution = Vector::read(&mut reader, |r| r.read_u8())?;
|
let solution = Vector::read(&mut reader, |r| r.read_u8())?;
|
||||||
|
|
||||||
Ok(BlockHeader(BlockHeaderData {
|
BlockHeader::from_data(BlockHeaderData {
|
||||||
version,
|
version,
|
||||||
prev_block,
|
prev_block,
|
||||||
merkle_root,
|
merkle_root,
|
||||||
|
@ -79,7 +102,7 @@ impl BlockHeader {
|
||||||
bits,
|
bits,
|
||||||
nonce,
|
nonce,
|
||||||
solution,
|
solution,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||||
|
@ -206,6 +229,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn header_read_write() {
|
fn header_read_write() {
|
||||||
let header = BlockHeader::read(&HEADER_MAINNET_415000[..]).unwrap();
|
let header = BlockHeader::read(&HEADER_MAINNET_415000[..]).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
format!("{}", header.hash()),
|
||||||
|
"0000000001ab37793ce771262b2ffa082519aa3fe891250a1adb43baaf856168"
|
||||||
|
);
|
||||||
let mut encoded = Vec::with_capacity(HEADER_MAINNET_415000.len());
|
let mut encoded = Vec::with_capacity(HEADER_MAINNET_415000.len());
|
||||||
header.write(&mut encoded).unwrap();
|
header.write(&mut encoded).unwrap();
|
||||||
assert_eq!(&HEADER_MAINNET_415000[..], &encoded[..]);
|
assert_eq!(&HEADER_MAINNET_415000[..], &encoded[..]);
|
||||||
|
|
Loading…
Reference in New Issue