Adding BlockHeader, BlockHash, MerkleRootHash, Sha256dWriter
This commit is contained in:
parent
00494d4963
commit
7340c7d9ce
|
@ -1,26 +1,62 @@
|
|||
//! Definitions of block datastructures.
|
||||
|
||||
use crate::transaction::Transaction;
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::io;
|
||||
|
||||
use crate::merkle_tree::MerkleTree;
|
||||
use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
|
||||
use crate::sha256d_writer::Sha256dWriter;
|
||||
use crate::transaction::Transaction;
|
||||
|
||||
/// A SHA-256d hash of a BlockHeader.
|
||||
///
|
||||
/// This is useful when one block header is pointing to its parent
|
||||
/// block header in the block chain. ⛓️
|
||||
pub struct BlockHash([u8; 32]);
|
||||
|
||||
impl From<BlockHeader> for BlockHash {
|
||||
fn from(block_header: BlockHeader) -> Self {
|
||||
let mut hash_writer = Sha256dWriter::default();
|
||||
block_header
|
||||
.zcash_serialize(&mut hash_writer)
|
||||
.expect("Block headers must serialize.");
|
||||
Self(hash_writer.finish())
|
||||
}
|
||||
}
|
||||
|
||||
/// A SHA-256d hash of the root node of a merkle tree of SHA256-d
|
||||
/// hashed transactions in a block.
|
||||
pub struct MerkleRootHash([u8; 32]);
|
||||
|
||||
impl From<MerkleTree<Transaction>> for MerkleRootHash {
|
||||
fn from(merkle_tree: MerkleTree<Transaction>) -> Self {
|
||||
let mut hash_writer = Sha256dWriter::default();
|
||||
merkle_tree
|
||||
.zcash_serialize(&mut hash_writer)
|
||||
.expect("The merkle tree of transactions must serialize.");
|
||||
Self(hash_writer.finish())
|
||||
}
|
||||
}
|
||||
|
||||
/// Block header
|
||||
pub struct BlockHeader {
|
||||
/// A SHA-256d hash in internal byte order of the previous block’s
|
||||
/// header. This ensures no previous block can be changed without
|
||||
/// also changing this block’s header .
|
||||
previous_block_hash: [u8; 32],
|
||||
previous_block_hash: BlockHash,
|
||||
|
||||
/// A SHA-256d hash in internal byte order. The merkle root is
|
||||
/// derived from the hashes of all transactions included in this
|
||||
/// block, ensuring that none of those transactions can be modied
|
||||
/// without modifying the header.
|
||||
/// derived from the SHA256d hashes of all transactions included
|
||||
/// in this block as assembled in a binary tree, ensuring that
|
||||
/// none of those transactions can be modied without modifying the
|
||||
/// header.
|
||||
merkle_root_hash: [u8; 32],
|
||||
|
||||
/// [Sapling onward] The root LEBS2OSP256(rt) of the Sapling note
|
||||
/// commitment tree corresponding to the nal Sapling treestate of
|
||||
/// this block.
|
||||
// TODO: replace type with custom SaplingRoot or similar type
|
||||
// hash_final_sapling_root: [u8; 32],
|
||||
// hash_final_sapling_root: SaplingRootHash,
|
||||
|
||||
/// The block timestamp is a Unix epoch time (UTC) when the miner
|
||||
/// started hashing the header (according to the miner).
|
||||
|
@ -55,12 +91,24 @@ impl BlockHeader {
|
|||
}
|
||||
}
|
||||
|
||||
impl ZcashSerialize for BlockHeader {
|
||||
fn zcash_serialize<W: io::Write>(&self, writer: W) -> Result<(), SerializationError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl ZcashDeserialize for BlockHeader {
|
||||
fn zcash_deserialize<R: io::Read>(reader: R) -> Result<Self, SerializationError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
/// A block in your blockchain.
|
||||
pub struct Block {
|
||||
/// First 80 bytes of the block as defined by the encoding used by
|
||||
/// "block" messages
|
||||
/// "block" messages.
|
||||
pub header: BlockHeader,
|
||||
|
||||
///
|
||||
/// Block transactions.
|
||||
pub transactions: Vec<Transaction>,
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#[macro_use]
|
||||
extern crate failure;
|
||||
|
||||
mod merkle_tree;
|
||||
mod sha256d_writer;
|
||||
|
||||
pub mod block;
|
||||
pub mod serialization;
|
||||
pub mod transaction;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
//! A binary hash tree of SHA256d (two rounds of SHA256) hashes for
|
||||
//! node values.
|
||||
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
|
||||
|
||||
/// A binary hash tree of SHA256d (two rounds of SHA256) hashes for
|
||||
/// node values.
|
||||
#[derive(Default)]
|
||||
pub struct MerkleTree<T> {
|
||||
leaves: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> MerkleTree<T> {
|
||||
pub fn get_root(&self) -> Sha256 {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ZcashSerialize for MerkleTree<T> {
|
||||
fn zcash_serialize<W: io::Write>(&self, writer: W) -> Result<(), SerializationError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ZcashDeserialize for MerkleTree<T> {
|
||||
fn zcash_deserialize<R: io::Read>(reader: R) -> Result<Self, SerializationError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
//! A Writer for Sha256d-related (two rounds of SHA256) types.
|
||||
|
||||
use std::io::prelude::*;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
/// A type that lets you write out SHA256d (double-SHA256, as in two rounds).
|
||||
#[derive(Default)]
|
||||
pub struct Sha256dWriter {
|
||||
hash: Sha256,
|
||||
}
|
||||
|
||||
impl Sha256dWriter {
|
||||
/// Consume the Writer and produce the hash result.
|
||||
pub fn finish(self) -> [u8; 32] {
|
||||
let result1 = self.hash.result();
|
||||
let result2 = Sha256::digest(&result1);
|
||||
let mut buffer = [0u8; 32];
|
||||
buffer[0..32].copy_from_slice(&result2[0..32]);
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Sha256dWriter {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
self.hash.input(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
//! Newtype wrappers for primitive data types with semantic meaning.
|
||||
|
||||
/// A 4-byte checksum using truncated double SHA256.
|
||||
/// A 4-byte checksum using truncated double-SHA256 (two rounds of SHA256).
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Sha256dChecksum(pub [u8; 4]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue