moved creation of blockchains db transaction to apply_update function

This commit is contained in:
debris 2016-02-27 10:19:33 +01:00
parent d57518d90c
commit 01f69ca80c
2 changed files with 65 additions and 73 deletions

View File

@ -417,23 +417,23 @@ impl BlockChain {
// store block in db // store block in db
self.blocks_db.put(&hash, &bytes).unwrap(); self.blocks_db.put(&hash, &bytes).unwrap();
let batch = DBTransaction::new();
let info = self.block_info(bytes); let info = self.block_info(bytes);
batch.put(b"best", &info.hash).unwrap();
self.apply_update(ExtrasUpdate { self.apply_update(ExtrasUpdate {
block_numbers: self.prepare_block_hashes_update(bytes, &info, &batch), block_hashes: self.prepare_block_hashes_update(bytes, &info),
block_details_hashes: self.prepare_block_details_update(bytes, &info, &batch), block_details: self.prepare_block_details_update(bytes, &info),
block_receipts_hashes: self.prepare_block_receipts_update(receipts, &info, &batch), block_receipts: self.prepare_block_receipts_update(receipts, &info),
transactions_addresses_hashes: self.prepare_transaction_addresses_update(bytes, &info, &batch), transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info),
bloom_hashes: self.prepare_block_blooms_update(bytes, &info, &batch), blocks_blooms: self.prepare_block_blooms_update(bytes, &info),
batch: batch,
info: info info: info
}); });
} }
/// Applies extras update. /// Applies extras update.
fn apply_update(&self, update: ExtrasUpdate) { fn apply_update(&self, update: ExtrasUpdate) {
let batch = DBTransaction::new();
batch.put(b"best", &update.info.hash).unwrap();
// update best block // update best block
let mut best_block = self.best_block.write().unwrap(); let mut best_block = self.best_block.write().unwrap();
match update.info.location { match update.info.location {
@ -448,32 +448,37 @@ impl BlockChain {
} }
let mut write_hashes = self.block_hashes.write().unwrap(); let mut write_hashes = self.block_hashes.write().unwrap();
for number in &update.block_numbers { for (number, hash) in &update.block_hashes {
batch.put_extras(number, hash);
write_hashes.remove(number); write_hashes.remove(number);
} }
let mut write_details = self.block_details.write().unwrap(); let mut write_details = self.block_details.write().unwrap();
for hash in &update.block_details_hashes { for (hash, details) in update.block_details.into_iter() {
write_details.remove(hash); batch.put_extras(&hash, &details);
write_details.insert(hash, details);
} }
let mut write_receipts = self.block_receipts.write().unwrap(); let mut write_receipts = self.block_receipts.write().unwrap();
for hash in &update.block_receipts_hashes { for (hash, receipt) in &update.block_receipts {
batch.put_extras(hash, receipt);
write_receipts.remove(hash); write_receipts.remove(hash);
} }
let mut write_txs = self.transaction_addresses.write().unwrap(); let mut write_txs = self.transaction_addresses.write().unwrap();
for hash in &update.transactions_addresses_hashes { for (hash, tx_address) in &update.transactions_addresses {
batch.put_extras(hash, tx_address);
write_txs.remove(hash); write_txs.remove(hash);
} }
let mut write_blocks_blooms = self.blocks_blooms.write().unwrap(); let mut write_blocks_blooms = self.blocks_blooms.write().unwrap();
for bloom_hash in &update.bloom_hashes { for (bloom_hash, blocks_bloom) in &update.blocks_blooms {
batch.put_extras(bloom_hash, blocks_bloom);
write_blocks_blooms.remove(bloom_hash); write_blocks_blooms.remove(bloom_hash);
} }
//// update extras database // update extras database
self.extras_db.write(update.batch).unwrap(); self.extras_db.write(batch).unwrap();
} }
/// Get inserted block info which is critical to preapre extras updates. /// Get inserted block info which is critical to preapre extras updates.
@ -514,40 +519,35 @@ impl BlockChain {
} }
} }
/// This function updates block number to block hash mappings and writes them to db batch. /// This function returns modified block hashes.
/// fn prepare_block_hashes_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<BlockNumber, H256> {
/// Returns modified block numbers. let mut block_hashes = HashMap::new();
fn prepare_block_hashes_update(&self, block_bytes: &[u8], info: &BlockInfo, batch: &DBTransaction) -> HashSet<BlockNumber> {
let block = BlockView::new(block_bytes); let block = BlockView::new(block_bytes);
let header = block.header_view(); let header = block.header_view();
let number = header.number(); let number = header.number();
match info.location { match info.location {
BlockLocation::Branch => vec![], BlockLocation::Branch => (),
BlockLocation::CanonChain => { BlockLocation::CanonChain => {
batch.put_extras(&number, &info.hash); block_hashes.insert(number, info.hash.clone());
vec![number]
}, },
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref route } => { BlockLocation::BranchBecomingCanonChain { ref ancestor, ref route } => {
let ancestor_number = self.block_number(ancestor).unwrap(); let ancestor_number = self.block_number(ancestor).unwrap();
let start_number = ancestor_number + 1; let start_number = ancestor_number + 1;
for (index, hash) in route.iter().enumerate() { for (index, hash) in route.iter().cloned().enumerate() {
batch.put_extras(&(start_number + index as BlockNumber), hash); block_hashes.insert(start_number + index as BlockNumber, hash);
} }
batch.put_extras(&number, &info.hash); block_hashes.insert(number, info.hash.clone());
let mut numbers: Vec<BlockNumber> = (start_number..start_number + route.len() as BlockNumber).into_iter().collect();
numbers.push(number);
numbers
} }
}.into_iter().collect() }
block_hashes
} }
/// This function creates current block details, updates parent block details and writes them to db batch. /// This function returns modified block details.
/// fn prepare_block_details_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<H256, BlockDetails> {
/// Returns hashes of modified block details.
fn prepare_block_details_update(&self, block_bytes: &[u8], info: &BlockInfo, batch: &DBTransaction) -> HashSet<H256> {
let block = BlockView::new(block_bytes); let block = BlockView::new(block_bytes);
let header = block.header_view(); let header = block.header_view();
let parent_hash = header.parent_hash(); let parent_hash = header.parent_hash();
@ -565,39 +565,39 @@ impl BlockChain {
}; };
// write to batch // write to batch
batch.put_extras(&parent_hash, &parent_details); let mut block_details = HashMap::new();
batch.put_extras(&info.hash, &details); block_details.insert(parent_hash, parent_details);
vec![parent_hash, info.hash.clone()].into_iter().collect() block_details.insert(info.hash.clone(), details);
block_details
} }
/// This function writes block receipts to db batch and returns hashes of modified receipts. /// This function returns modified block receipts.
fn prepare_block_receipts_update(&self, receipts: Vec<Receipt>, info: &BlockInfo, batch: &DBTransaction) -> HashSet<H256> { fn prepare_block_receipts_update(&self, receipts: Vec<Receipt>, info: &BlockInfo) -> HashMap<H256, BlockReceipts> {
batch.put_extras(&info.hash, &BlockReceipts::new(receipts)); let mut block_receipts = HashMap::new();
vec![info.hash.clone()].into_iter().collect() block_receipts.insert(info.hash.clone(), BlockReceipts::new(receipts));
block_receipts
} }
/// This function writes mapping from transaction hash to transaction address to database. /// This function returns modified transaction addresses.
/// fn prepare_transaction_addresses_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<H256, TransactionAddress> {
/// Returns hashes of modified mappings.
fn prepare_transaction_addresses_update(&self, block_bytes: &[u8], info: &BlockInfo, batch: &DBTransaction) -> HashSet<H256> {
let block = BlockView::new(block_bytes); let block = BlockView::new(block_bytes);
let transaction_hashes = block.transaction_hashes(); let transaction_hashes = block.transaction_hashes();
// update transaction addresses transaction_hashes.into_iter()
for (i, tx_hash) in transaction_hashes.iter().enumerate() { .enumerate()
batch.put_extras(tx_hash, &TransactionAddress { .fold(HashMap::new(), |mut acc, (i ,tx_hash)| {
block_hash: info.hash.clone(), acc.insert(tx_hash, TransactionAddress {
index: i block_hash: info.hash.clone(),
}); index: i
} });
acc
transaction_hashes.into_iter().collect() })
} }
/// This functions update blcoks blooms and writes them to db batch. /// This functions returns modified blocks blooms.
/// ///
/// TODO: this function needs comprehensive description. /// TODO: this function needs comprehensive description.
fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo, batch: &DBTransaction) -> HashSet<H256> { fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<H256, BlocksBlooms> {
let block = BlockView::new(block_bytes); let block = BlockView::new(block_bytes);
let header = block.header_view(); let header = block.header_view();
@ -623,7 +623,7 @@ impl BlockChain {
} }
}; };
let indexed_blocks_blooms = modified_blooms.into_iter() modified_blooms.into_iter()
.fold(HashMap::new(), | mut acc, (bloom_index, bloom) | { .fold(HashMap::new(), | mut acc, (bloom_index, bloom) | {
{ {
let location = self.bloom_indexer.location(&bloom_index); let location = self.bloom_indexer.location(&bloom_index);
@ -634,13 +634,7 @@ impl BlockChain {
blocks_blooms.blooms[location.index] = bloom; blocks_blooms.blooms[location.index] = bloom;
} }
acc acc
}); })
for (bloom_hash, blocks_blooms) in &indexed_blocks_blooms {
batch.put_extras(bloom_hash, blocks_blooms);
}
indexed_blocks_blooms.into_iter().map(|(bloom_hash, _)| bloom_hash).collect()
} }
/// Get best block hash. /// Get best block hash.

View File

@ -1,23 +1,21 @@
use std::collections::HashSet; use std::collections::HashMap;
use util::hash::H256; use util::hash::H256;
use util::kvdb::DBTransaction;
use header::BlockNumber; use header::BlockNumber;
use blockchain::block_info::BlockInfo; use blockchain::block_info::BlockInfo;
use extras::{BlockDetails, BlockReceipts, TransactionAddress, BlocksBlooms};
/// Block extras update info. /// Block extras update info.
pub struct ExtrasUpdate { pub struct ExtrasUpdate {
/// Block info. /// Block info.
pub info: BlockInfo, pub info: BlockInfo,
/// DB update batch.
pub batch: DBTransaction,
/// Numbers of blocks to update in block hashes cache. /// Numbers of blocks to update in block hashes cache.
pub block_numbers: HashSet<BlockNumber>, pub block_hashes: HashMap<BlockNumber, H256>,
/// Hashes of blocks to update in block details cache. /// Hashes of blocks to update in block details cache.
pub block_details_hashes: HashSet<H256>, pub block_details: HashMap<H256, BlockDetails>,
/// Hashes of receipts to update in block receipts cache. /// Hashes of receipts to update in block receipts cache.
pub block_receipts_hashes: HashSet<H256>, pub block_receipts: HashMap<H256, BlockReceipts>,
/// Hashes of transactions to update in transactions addresses cache. /// Hashes of transactions to update in transactions addresses cache.
pub transactions_addresses_hashes: HashSet<H256>, pub transactions_addresses: HashMap<H256, TransactionAddress>,
/// Changed blocks bloom location hashes. /// Changed blocks bloom location hashes.
pub bloom_hashes: HashSet<H256>, pub blocks_blooms: HashMap<H256, BlocksBlooms>,
} }