This commit is contained in:
debris 2015-12-14 14:15:27 +01:00
parent 4a4d5e638f
commit debf88db5d

View File

@ -9,6 +9,7 @@ use util::rlp::*;
use util::hashdb::*; use util::hashdb::*;
use util::overlaydb::*; use util::overlaydb::*;
use util::sha3::*; use util::sha3::*;
use util::bytes::*;
use blockheader::*; use blockheader::*;
use block::*; use block::*;
use verifiedblock::*; use verifiedblock::*;
@ -19,22 +20,26 @@ use extras::*;
pub struct BlockChain { pub struct BlockChain {
// rlp list of 3 // rlp list of 3
genesis_block: Vec<u8>, genesis_block: Bytes,
// genesis block header // genesis block header
genesis_header: Vec<u8>, genesis_header: Bytes,
genesis_hash: H256, genesis_hash: H256,
genesis_state: HashMap<Address, Account>, genesis_state: HashMap<Address, Account>,
last_block_number: U256, last_block_number: U256,
// extras // block cache
block_details_hash: Extras<H256, BlockDetails>, blocks: RwLock<HashMap<H256, Bytes>>,
block_hashes_hash: Extras<U256, H256>,
transaction_addresses_hash: Extras<H256, TransactionAddress>,
block_logs_hash: Extras<H256, BlockLogBlooms>,
blocks_blooms_hash: Extras<H256, BlocksBlooms>,
extras_db: DB // extra caches
block_details: Extras<H256, BlockDetails>,
block_hashes: Extras<U256, H256>,
transaction_addresses: Extras<H256, TransactionAddress>,
block_logs: Extras<H256, BlockLogBlooms>,
blocks_blooms: Extras<H256, BlocksBlooms>,
extras_db: DB,
blocks_db: DB
} }
impl BlockChain { impl BlockChain {
@ -75,13 +80,21 @@ impl BlockChain {
children: vec![] children: vec![]
}; };
let db = DB::open_default(path.to_str().unwrap()).unwrap(); let mut extras_path = path.to_path_buf();
extras_path.push("extras");
let extras_db = DB::open_default(extras_path.to_str().unwrap()).unwrap();
let mut blocks_path = path.to_path_buf();
blocks_path.push("blocks");
let blocks_db = DB::open_default(blocks_path.to_str().unwrap()).unwrap();
{ {
let mut batch = WriteBatch::new(); let mut batch = WriteBatch::new();
batch.put(&genesis_hash.to_extras_slice(ExtrasIndex::BlockDetails), &encode(&genesis_details)); batch.put(&genesis_hash.to_extras_slice(ExtrasIndex::BlockDetails), &encode(&genesis_details));
batch.put(&U256::from(0u8).to_extras_slice(ExtrasIndex::BlockHash), &encode(&genesis_hash)); batch.put(&U256::from(0u8).to_extras_slice(ExtrasIndex::BlockHash), &encode(&genesis_hash));
db.write(batch); extras_db.write(batch);
blocks_db.put(&genesis_hash, &genesis_header);
} }
BlockChain { BlockChain {
@ -90,15 +103,18 @@ impl BlockChain {
genesis_hash: genesis_hash, genesis_hash: genesis_hash,
genesis_state: genesis_state, genesis_state: genesis_state,
last_block_number: U256::from(0u8), last_block_number: U256::from(0u8),
block_details_hash: Extras::new(ExtrasIndex::BlockDetails), blocks: RwLock::new(HashMap::new()),
block_hashes_hash: Extras::new(ExtrasIndex::BlockHash), block_details: Extras::new(ExtrasIndex::BlockDetails),
transaction_addresses_hash: Extras::new(ExtrasIndex::TransactionAddress), block_hashes: Extras::new(ExtrasIndex::BlockHash),
block_logs_hash: Extras::new(ExtrasIndex::BlockLogBlooms), transaction_addresses: Extras::new(ExtrasIndex::TransactionAddress),
blocks_blooms_hash: Extras::new(ExtrasIndex::BlocksBlooms), block_logs: Extras::new(ExtrasIndex::BlockLogBlooms),
extras_db: db blocks_blooms: Extras::new(ExtrasIndex::BlocksBlooms),
extras_db: extras_db,
blocks_db: blocks_db
} }
} }
/// Returns reference to genesis hash
pub fn genesis_hash(&self) -> &H256 { pub fn genesis_hash(&self) -> &H256 {
&self.genesis_hash &self.genesis_hash
} }
@ -141,7 +157,7 @@ impl BlockChain {
/// Get the hash of given block's number /// Get the hash of given block's number
pub fn number_hash(&self, hash: &U256) -> Option<H256> { pub fn number_hash(&self, hash: &U256) -> Option<H256> {
self.query_extras(hash, &self.block_hashes_hash) self.query_extras(hash, &self.block_hashes)
} }
/// Returns true if the given block is known /// Returns true if the given block is known
@ -150,12 +166,35 @@ impl BlockChain {
// TODO: first do lookup in blocks_db for given hash // TODO: first do lookup in blocks_db for given hash
// TODO: consider taking into account current block // TODO: consider taking into account current block
match self.query_extras(hash, &self.block_details_hash) { match self.query_extras(hash, &self.block_details) {
None => false, None => false,
Some(details) => details.number <= self.last_block_number Some(details) => details.number <= self.last_block_number
} }
} }
pub fn block(&self, hash: &H256) -> Option<Bytes> {
{
let read = self.blocks.read().unwrap();
match read.get(hash) {
Some(v) => return Some(v.clone()),
None => ()
}
}
let opt = self.blocks_db.get(hash)
.expect("Low level database error. Some issue with disk?");
match opt {
Some(b) => {
let bytes: Bytes = b.to_vec();
let mut write = self.blocks.write().unwrap();
write.insert(hash.clone(), bytes.clone());
Some(bytes)
},
None => None
}
}
pub fn query_extras<K, T>(&self, hash: &K, cache: &Extras<K, T>) -> Option<T> where pub fn query_extras<K, T>(&self, hash: &K, cache: &Extras<K, T>) -> Option<T> where
T: Clone + Decodable, T: Clone + Decodable,
K: ExtrasSliceConvertable + Eq + Hash + Clone { K: ExtrasSliceConvertable + Eq + Hash + Clone {