hash block and transactions while reading them
This commit is contained in:
parent
591a642121
commit
ce7af59ad3
|
@ -173,6 +173,7 @@ name = "db"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitcrypto 0.1.0",
|
||||
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chain 0.1.0",
|
||||
"elastic-array 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -2,11 +2,11 @@ extern crate crypto as rcrypto;
|
|||
extern crate primitives;
|
||||
extern crate siphasher;
|
||||
|
||||
pub use rcrypto::digest::Digest;
|
||||
use std::hash::Hasher;
|
||||
use rcrypto::sha1::Sha1;
|
||||
use rcrypto::sha2::Sha256;
|
||||
use rcrypto::ripemd160::Ripemd160;
|
||||
use rcrypto::digest::Digest;
|
||||
use siphasher::sip::SipHasher24;
|
||||
use primitives::hash::{H32, H160, H256};
|
||||
|
||||
|
@ -72,6 +72,12 @@ impl DHash256 {
|
|||
pub fn new() -> Self {
|
||||
DHash256::default()
|
||||
}
|
||||
|
||||
pub fn finish(mut self) -> H256 {
|
||||
let mut result = H256::default();
|
||||
self.result(&mut *result);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Digest for DHash256 {
|
||||
|
|
|
@ -8,6 +8,7 @@ elastic-array = "0.5"
|
|||
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
primitives = { path = "../primitives" }
|
||||
bitcrypto = { path = "../crypto" }
|
||||
byteorder = "0.5"
|
||||
chain = { path = "../chain" }
|
||||
serialization = { path = "../serialization" }
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
use std::io;
|
||||
use primitives::hash::H256;
|
||||
use chain::{Block, OutPoint, TransactionOutput, merkle_root, Transaction};
|
||||
use serialization::{Serializable, serialized_list_size};
|
||||
use serialization::{
|
||||
Serializable, serialized_list_size,
|
||||
Deserializable, Reader, Error as ReaderError
|
||||
};
|
||||
use indexed_header::IndexedBlockHeader;
|
||||
use indexed_transaction::IndexedTransaction;
|
||||
use {TransactionOutputObserver, PreviousTransactionOutputProvider};
|
||||
|
@ -87,3 +91,14 @@ impl IndexedBlock {
|
|||
self.transactions.iter().all(|tx| tx.raw.is_final(height, self.header.raw.time))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserializable for IndexedBlock {
|
||||
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
|
||||
let block = IndexedBlock {
|
||||
header: try!(reader.read()),
|
||||
transactions: try!(reader.read_list()),
|
||||
};
|
||||
|
||||
Ok(block)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use std::io;
|
||||
use primitives::hash::H256;
|
||||
use chain::BlockHeader;
|
||||
use serialization::{Deserializable, Reader, Error as ReaderError};
|
||||
use read_and_hash::ReadAndHash;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IndexedBlockHeader {
|
||||
|
@ -24,3 +27,16 @@ impl IndexedBlockHeader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserializable for IndexedBlockHeader {
|
||||
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
|
||||
let data = try!(reader.read_and_hash::<BlockHeader>());
|
||||
// TODO: use len
|
||||
let header = IndexedBlockHeader {
|
||||
raw: data.data,
|
||||
hash: data.hash,
|
||||
};
|
||||
|
||||
Ok(header)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::cmp;
|
||||
use std::{cmp, io};
|
||||
use primitives::hash::H256;
|
||||
use chain::{Transaction, OutPoint, TransactionOutput};
|
||||
use serialization::{Deserializable, Reader, Error as ReaderError};
|
||||
use read_and_hash::ReadAndHash;
|
||||
use PreviousTransactionOutputProvider;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -33,6 +35,19 @@ impl cmp::PartialEq for IndexedTransaction {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deserializable for IndexedTransaction {
|
||||
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
|
||||
let data = try!(reader.read_and_hash::<Transaction>());
|
||||
// TODO: use len
|
||||
let tx = IndexedTransaction {
|
||||
raw: data.data,
|
||||
hash: data.hash,
|
||||
};
|
||||
|
||||
Ok(tx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PreviousTransactionOutputProvider for &'a [IndexedTransaction] {
|
||||
fn previous_transaction_output(&self, prevout: &OutPoint) -> Option<TransactionOutput> {
|
||||
self.iter()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Bitcoin database
|
||||
|
||||
extern crate bitcrypto as crypto;
|
||||
extern crate elastic_array;
|
||||
extern crate rocksdb;
|
||||
extern crate parking_lot;
|
||||
|
@ -31,6 +32,7 @@ mod update_context;
|
|||
mod indexed_block;
|
||||
mod indexed_header;
|
||||
mod indexed_transaction;
|
||||
mod read_and_hash;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BlockRef {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
use std::io;
|
||||
use crypto::{DHash256, Digest};
|
||||
use primitives::hash::H256;
|
||||
use serialization::{Reader, Error as ReaderError, Deserializable};
|
||||
|
||||
pub struct HashedData<T> {
|
||||
pub len: usize,
|
||||
pub hash: H256,
|
||||
pub data: T,
|
||||
}
|
||||
|
||||
pub trait ReadAndHash {
|
||||
fn read_and_hash<T>(&mut self) -> Result<HashedData<T>, ReaderError> where T: Deserializable;
|
||||
}
|
||||
|
||||
impl<R> ReadAndHash for Reader<R> where R: io::Read {
|
||||
fn read_and_hash<T>(&mut self) -> Result<HashedData<T>, ReaderError> where T: Deserializable {
|
||||
let mut len = 0usize;
|
||||
let mut hasher = DHash256::new();
|
||||
let data = self.read_with_proxy(|bytes| {
|
||||
len += bytes.len();
|
||||
hasher.input(bytes);
|
||||
})?;
|
||||
|
||||
let result = HashedData {
|
||||
hash: hasher.finish(),
|
||||
data: data,
|
||||
len: len,
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
|
@ -84,6 +84,11 @@ impl<R> Reader<R> where R: io::Read {
|
|||
T::deserialize(self)
|
||||
}
|
||||
|
||||
pub fn read_with_proxy<T, F>(&mut self, proxy: F) -> Result<T, Error> where T: Deserializable, F: FnMut(&[u8]) {
|
||||
let mut reader = Reader::from_read(Proxy::new(self, proxy));
|
||||
T::deserialize(&mut reader)
|
||||
}
|
||||
|
||||
pub fn read_slice(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
|
||||
io::Read::read_exact(self, bytes).map_err(|_| Error::UnexpectedEnd)
|
||||
}
|
||||
|
@ -148,3 +153,26 @@ impl<R, T> Iterator for ReadIterator<R, T> where R: io::Read, T: Deserializable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Proxy<F, T> {
|
||||
from: F,
|
||||
to: T,
|
||||
}
|
||||
|
||||
impl<F, T> Proxy<F, T> {
|
||||
fn new(from: F, to: T) -> Self {
|
||||
Proxy {
|
||||
from: from,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, T> io::Read for Proxy<F, T> where F: io::Read, T: FnMut(&[u8]) {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
let len = try!(io::Read::read(&mut self.from, buf));
|
||||
let to = &mut self.to;
|
||||
to(&buf[..len]);
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue