Changes tries build cache (#2933)

* changes tries build cache

added CT build cache test

* fix lines width

* fixed some grumbles

* clear cache when: digests disabled, top-level or skewed digest is built

* cached_changed_keys -> with_cached_changed_keys
This commit is contained in:
Svyatoslav Nikolsky
2019-09-05 08:27:04 +03:00
committed by GitHub
parent 932e51ffff
commit 551a9e6bcb
16 changed files with 620 additions and 66 deletions
+30 -6
View File
@@ -36,7 +36,7 @@ mod utils;
use std::sync::Arc;
use std::path::PathBuf;
use std::io;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use client::backend::NewBlockState;
use client::blockchain::HeaderBackend;
@@ -58,7 +58,7 @@ use sr_primitives::traits::{
};
use state_machine::backend::Backend as StateBackend;
use executor::RuntimeInfo;
use state_machine::{CodeExecutor, DBValue};
use state_machine::{CodeExecutor, DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache};
use crate::utils::{Meta, db_err, meta_keys, read_db, block_id_to_lookup_key, read_meta};
use client::leaves::{LeafSet, FinalizationDisplaced};
use client::children;
@@ -405,6 +405,7 @@ pub struct BlockImportOperation<Block: BlockT, H: Hasher> {
storage_updates: StorageCollection,
child_storage_updates: ChildStorageCollection,
changes_trie_updates: MemoryDB<H>,
changes_trie_cache_update: Option<ChangesTrieCacheAction<H::Out, NumberFor<Block>>>,
pending_block: Option<PendingBlock<Block>>,
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
finalized_blocks: Vec<(BlockId<Block>, Option<Justification>)>,
@@ -487,8 +488,12 @@ where Block: BlockT<Hash=H256>,
Ok(root)
}
fn update_changes_trie(&mut self, update: MemoryDB<Blake2Hasher>) -> Result<(), client::error::Error> {
self.changes_trie_updates = update;
fn update_changes_trie(
&mut self,
update: ChangesTrieTransaction<Blake2Hasher, NumberFor<Block>>,
) -> Result<(), client::error::Error> {
self.changes_trie_updates = update.0;
self.changes_trie_cache_update = Some(update.1);
Ok(())
}
@@ -565,6 +570,7 @@ pub struct DbChangesTrieStorage<Block: BlockT> {
db: Arc<dyn KeyValueDB>,
meta: Arc<RwLock<Meta<NumberFor<Block>, Block::Hash>>>,
min_blocks_to_keep: Option<u32>,
cache: RwLock<ChangesTrieBuildCache<Block::Hash, NumberFor<Block>>>,
_phantom: ::std::marker::PhantomData<Block>,
}
@@ -576,6 +582,11 @@ impl<Block: BlockT<Hash=H256>> DbChangesTrieStorage<Block> {
}
}
/// Commit changes into changes trie build cache.
pub fn commit_cache(&self, cache_update: ChangesTrieCacheAction<Block::Hash, NumberFor<Block>>) {
self.cache.write().perform(cache_update);
}
/// Prune obsolete changes tries.
pub fn prune(
&self,
@@ -699,6 +710,14 @@ where
self
}
fn with_cached_changed_keys(
&self,
root: &H256,
functor: &mut dyn FnMut(&HashMap<Option<Vec<u8>>, HashSet<Vec<u8>>>),
) -> bool {
self.cache.read().with_changed_keys(root, functor)
}
fn get(&self, key: &H256, _prefix: Prefix) -> Result<Option<DBValue>, String> {
self.db.get(columns::CHANGES_TRIE, &key[..])
.map_err(|err| format!("{}", err))
@@ -783,6 +802,7 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
db,
meta,
min_blocks_to_keep: if is_archive_pruning { None } else { Some(MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR) },
cache: RwLock::new(ChangesTrieBuildCache::new()),
_phantom: Default::default(),
};
@@ -1098,7 +1118,6 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
self.changes_tries_storage.commit(&mut transaction, changes_trie_updates);
let cache = operation.old_state.release(); // release state reference so that it can be finalized
if finalized {
// TODO: ensure best chain contains this block.
self.ensure_sequential_finalization(header, Some(last_finalized_hash))?;
@@ -1155,6 +1174,10 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
let write_result = self.storage.db.write(transaction).map_err(db_err);
if let Some(changes_trie_cache_update) = operation.changes_trie_cache_update {
self.changes_tries_storage.commit_cache(changes_trie_cache_update);
}
if let Some((number, hash, enacted, retracted, displaced_leaf, is_best, mut cache)) = imported {
if let Err(e) = write_result {
let mut leaves = self.blockchain.leaves.write();
@@ -1288,6 +1311,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
storage_updates: Default::default(),
child_storage_updates: Default::default(),
changes_trie_updates: MemoryDB::default(),
changes_trie_cache_update: None,
aux_ops: Vec::new(),
finalized_blocks: Vec::new(),
set_head: None,
@@ -1515,7 +1539,7 @@ mod tests {
let mut op = backend.begin_operation().unwrap();
backend.begin_state_operation(&mut op, block_id).unwrap();
op.set_block_data(header, None, None, NewBlockState::Best).unwrap();
op.update_changes_trie(changes_trie_update).unwrap();
op.update_changes_trie((changes_trie_update, ChangesTrieCacheAction::Clear)).unwrap();
backend.commit_operation(op).unwrap();
header_hash