Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3681c4f
Move authorities interface from Core to consensus
stanislav-tkach Jan 14, 2019
4cf9dcb
notify all caches of block insert + create with up-to-date best_fin
svyatonik Mar 22, 2019
8e5f853
merged authorities_are_cached from light_grandpa_import2
svyatonik Mar 22, 2019
6f5c6a6
Add ProvideCache trait
stanislav-tkach Mar 22, 2019
8d53b54
Create helper function for 'get_cache'
stanislav-tkach Mar 22, 2019
f7d3169
Fix some formatting
stanislav-tkach Mar 25, 2019
f9eb1d6
Bump impl version
stanislav-tkach Mar 26, 2019
25c21b8
Resolve wasm conflicts
stanislav-tkach Mar 27, 2019
13562a0
Apply review comments
stanislav-tkach Mar 28, 2019
2e8c27a
Use try_for_each
stanislav-tkach Mar 29, 2019
78b94e2
Move authorities interface from Core to consensus
stanislav-tkach Jan 14, 2019
c8882b0
notify all caches of block insert + create with up-to-date best_fin
svyatonik Mar 22, 2019
7150092
merged authorities_are_cached from light_grandpa_import2
svyatonik Mar 22, 2019
8d99ee3
Add ProvideCache trait
stanislav-tkach Mar 22, 2019
ee4cebc
Create helper function for 'get_cache'
stanislav-tkach Mar 22, 2019
cc8d4c5
Fix some formatting
stanislav-tkach Mar 25, 2019
d463937
Bump impl version
stanislav-tkach Mar 26, 2019
ad37c59
Resolve wasm conflicts
stanislav-tkach Mar 27, 2019
8de9520
Apply review comments
stanislav-tkach Mar 28, 2019
db6c584
Use try_for_each
stanislav-tkach Mar 29, 2019
853bc7f
devops-parity updated wasm runtime blobs 8bcd2591 and merged in maste…
devops-parity Mar 29, 2019
f65e167
Move authorities interface from Core to consensus
stanislav-tkach Jan 14, 2019
feea0a0
notify all caches of block insert + create with up-to-date best_fin
svyatonik Mar 22, 2019
f3697ea
merged authorities_are_cached from light_grandpa_import2
svyatonik Mar 22, 2019
d191d91
Add ProvideCache trait
stanislav-tkach Mar 22, 2019
f1de5a2
Create helper function for 'get_cache'
stanislav-tkach Mar 22, 2019
e431bb3
Fix some formatting
stanislav-tkach Mar 25, 2019
ec1d765
Bump impl version
stanislav-tkach Mar 26, 2019
2df0944
Resolve wasm conflicts
stanislav-tkach Mar 27, 2019
8eee944
Apply review comments
stanislav-tkach Mar 28, 2019
d7b95a0
Use try_for_each
stanislav-tkach Mar 29, 2019
bd2f7ca
Merge branch 'stas-1369-move-authorities-from-core' of github.com:par…
gavofyork Mar 29, 2019
9aa6f38
Merge branch 'stas-1369-move-authorities-from-core' of github.com:par…
gavofyork Mar 29, 2019
4c9fcfb
Increment impl_version
stanislav-tkach Mar 29, 2019
55d2a69
Update lib.rs
gavofyork Mar 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ impl_runtime_apis! {
VERSION
}

fn authorities() -> Vec<SessionKey> {
Consensus::authorities()
}

fn execute_block(block: Block) {
Executive::execute_block(block)
}
Expand Down
1 change: 1 addition & 0 deletions core/client/db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ trie = { package = "substrate-trie", path = "../../trie" }
kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" }
substrate-keyring = { path = "../../keyring" }
test-client = { package = "substrate-test-client", path = "../../test-client" }
consensus_common = { package = "substrate-consensus-common", path = "../../consensus/common" }
env_logger = { version = "0.6" }

[features]
Expand Down
170 changes: 123 additions & 47 deletions core/client/db/src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! DB-backed cache of blockchain data.

use std::sync::Arc;
use std::{sync::Arc, collections::HashMap};
use parking_lot::RwLock;

use kvdb::{KeyValueDB, DBTransaction};
Expand All @@ -25,7 +25,7 @@ use client::blockchain::Cache as BlockchainCache;
use client::error::Result as ClientResult;
use parity_codec::{Encode, Decode};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As, AuthorityIdFor};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As};
use crate::utils::{self, COLUMN_META};

use self::list_cache::ListCache;
Expand Down Expand Up @@ -64,7 +64,12 @@ impl<T> CacheItemT for T where T: Clone + Decode + Encode + PartialEq {}

/// Database-backed blockchain data cache.
pub struct DbCache<Block: BlockT> {
authorities_at: ListCache<Block, Vec<AuthorityIdFor<Block>>, self::list_storage::DbStorage>,
cache_at: HashMap<Vec<u8>, ListCache<Block, Vec<u8>, self::list_storage::DbStorage>>,
db: Arc<KeyValueDB>,
key_lookup_column: Option<u32>,
header_column: Option<u32>,
authorities_column: Option<u32>,
best_finalized_block: ComplexBlockId<Block>,
}

impl<Block: BlockT> DbCache<Block> {
Expand All @@ -76,19 +81,13 @@ impl<Block: BlockT> DbCache<Block> {
authorities_column: Option<u32>,
best_finalized_block: ComplexBlockId<Block>,
) -> Self {
DbCache {
authorities_at: ListCache::new(
self::list_storage::DbStorage::new(b"auth".to_vec(), db,
self::list_storage::DbColumns {
meta: COLUMN_META,
key_lookup: key_lookup_column,
header: header_column,
cache: authorities_column,
},
),
As::sa(PRUNE_DEPTH),
best_finalized_block,
),
Self {
cache_at: HashMap::new(),
db,
key_lookup_column,
header_column,
authorities_column,
best_finalized_block,
}
}

Expand All @@ -97,35 +96,82 @@ impl<Block: BlockT> DbCache<Block> {
DbCacheTransaction {
cache: self,
tx,
authorities_at_op: None,
cache_at_op: HashMap::new(),
best_finalized_block: None,
}
}

/// Run post-commit cache operations.
pub fn commit(&mut self, ops: DbCacheTransactionOps<Block>) {
if let Some(authorities_at_op) = ops.authorities_at_op {
self.authorities_at.on_transaction_commit(authorities_at_op);
for (name, op) in ops.cache_at_op.into_iter() {
self.get_cache(name).on_transaction_commit(op);
}
if let Some(best_finalized_block) = ops.best_finalized_block {
self.best_finalized_block = best_finalized_block;
}
}

/// Creates `ListCache` with the given name or returns a reference to the existing.
fn get_cache(&mut self, name: Vec<u8>) -> &mut ListCache<Block, Vec<u8>, self::list_storage::DbStorage> {
get_cache_helper(
&mut self.cache_at,
name,
&self.db,
self.key_lookup_column,
self.header_column,
self.authorities_column,
&self.best_finalized_block
)
}
}

// This helper is needed because otherwise the borrow checker will require to
// clone all parameters outside of the closure.
fn get_cache_helper<'a, Block: BlockT>(
cache_at: &'a mut HashMap<Vec<u8>, ListCache<Block, Vec<u8>, self::list_storage::DbStorage>>,
name: Vec<u8>,
db: &Arc<KeyValueDB>,
key_lookup: Option<u32>,
header: Option<u32>,
cache: Option<u32>,
best_finalized_block: &ComplexBlockId<Block>,
) -> &'a mut ListCache<Block, Vec<u8>, self::list_storage::DbStorage> {
cache_at.entry(name.clone()).or_insert_with(|| {
ListCache::new(
self::list_storage::DbStorage::new(name, db.clone(),
self::list_storage::DbColumns {
meta: COLUMN_META,
key_lookup,
header,
cache,
},
),
As::sa(PRUNE_DEPTH),
best_finalized_block.clone(),
)
})
}

/// Cache operations that are to be committed after database transaction is committed.
pub struct DbCacheTransactionOps<Block: BlockT> {
authorities_at_op: Option<self::list_cache::CommitOperation<Block, Vec<AuthorityIdFor<Block>>>>,
cache_at_op: HashMap<Vec<u8>, self::list_cache::CommitOperation<Block, Vec<u8>>>,
best_finalized_block: Option<ComplexBlockId<Block>>,
}

/// Database-backed blockchain data cache transaction valid for single block import.
pub struct DbCacheTransaction<'a, Block: BlockT> {
cache: &'a mut DbCache<Block>,
tx: &'a mut DBTransaction,
authorities_at_op: Option<self::list_cache::CommitOperation<Block, Vec<AuthorityIdFor<Block>>>>,
cache_at_op: HashMap<Vec<u8>, self::list_cache::CommitOperation<Block, Vec<u8>>>,
best_finalized_block: Option<ComplexBlockId<Block>>,
}

impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
/// Convert transaction into post-commit operations set.
pub fn into_ops(self) -> DbCacheTransactionOps<Block> {
DbCacheTransactionOps {
authorities_at_op: self.authorities_at_op,
cache_at_op: self.cache_at_op,
best_finalized_block: self.best_finalized_block,
}
}

Expand All @@ -134,21 +180,42 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
mut self,
parent: ComplexBlockId<Block>,
block: ComplexBlockId<Block>,
authorities_at: Option<Vec<AuthorityIdFor<Block>>>,
data_at: HashMap<Vec<u8>, Vec<u8>>,
is_final: bool,
) -> ClientResult<Self> {
assert!(self.authorities_at_op.is_none());
assert!(self.cache_at_op.is_empty());

self.authorities_at_op = self.cache.authorities_at.on_block_insert(
&mut self::list_storage::DbStorageTransaction::new(
self.cache.authorities_at.storage(),
&mut self.tx
),
parent,
block,
authorities_at,
is_final,
)?;
// prepare list of caches that are not update
// (we might still need to do some cache maintenance in this case)
let missed_caches = self.cache.cache_at.keys()
.filter(|cache| !data_at.contains_key(cache.clone()))
.cloned()
.collect::<Vec<_>>();

let mut insert_op = |name: Vec<u8>, value: Option<Vec<u8>>| -> Result<(), client::error::Error> {
let cache = self.cache.get_cache(name.clone());
let op = cache.on_block_insert(
&mut self::list_storage::DbStorageTransaction::new(
cache.storage(),
&mut self.tx,
),
parent.clone(),
block.clone(),
value.or(cache.value_at_block(&parent)?),
is_final,
)?;
if let Some(op) = op {
self.cache_at_op.insert(name, op);
}
Ok(())
};

data_at.into_iter().try_for_each(|(name, data)| insert_op(name, Some(data)))?;
missed_caches.into_iter().try_for_each(|name| insert_op(name, None))?;

if is_final {
self.best_finalized_block = Some(block);
}

Ok(self)
}
Expand All @@ -159,16 +226,24 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
parent: ComplexBlockId<Block>,
block: ComplexBlockId<Block>
) -> ClientResult<Self> {
assert!(self.authorities_at_op.is_none());
assert!(self.cache_at_op.is_empty());

self.authorities_at_op = self.cache.authorities_at.on_block_finalize(
&mut self::list_storage::DbStorageTransaction::new(
self.cache.authorities_at.storage(),
&mut self.tx
),
parent,
block,
)?;
for (name, cache_at) in self.cache.cache_at.iter() {
let op = cache_at.on_block_finalize(
&mut self::list_storage::DbStorageTransaction::new(
cache_at.storage(),
&mut self.tx
),
parent.clone(),
block.clone(),
)?;

if let Some(op) = op {
self.cache_at_op.insert(name.to_owned(), op);
}
}

self.best_finalized_block = Some(block);

Ok(self)
}
Expand All @@ -178,12 +253,12 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
pub struct DbCacheSync<Block: BlockT>(pub RwLock<DbCache<Block>>);

impl<Block: BlockT> BlockchainCache<Block> for DbCacheSync<Block> {
fn authorities_at(&self, at: BlockId<Block>) -> Option<Vec<AuthorityIdFor<Block>>> {
fn get_at(&self, key: &[u8], at: &BlockId<Block>) -> Option<Vec<u8>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will make future refactorings easier.

let cache = self.0.read();
let storage = cache.authorities_at.storage();
let storage = cache.cache_at.get(key)?.storage();
let db = storage.db();
let columns = storage.columns();
let at = match at {
let at = match *at {
BlockId::Hash(hash) => {
let header = utils::read_header::<Block>(
&**db,
Expand All @@ -202,6 +277,7 @@ impl<Block: BlockT> BlockchainCache<Block> for DbCacheSync<Block> {
},
};

cache.authorities_at.value_at_block(&at).ok()?
cache.cache_at.get(key)?.value_at_block(&at).ok()?
}
}

15 changes: 11 additions & 4 deletions core/client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ mod utils;
use std::sync::Arc;
use std::path::PathBuf;
use std::io;
use std::collections::HashMap;

use client::backend::NewBlockState;
use client::blockchain::HeaderBackend;
Expand All @@ -45,7 +46,7 @@ use parking_lot::RwLock;
use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash};
use primitives::storage::well_known_keys;
use runtime_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero, Digest, DigestItem, AuthorityIdFor};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero, Digest, DigestItem};
use runtime_primitives::BuildStorage;
use state_machine::backend::Backend as StateBackend;
use executor::RuntimeInfo;
Expand Down Expand Up @@ -243,7 +244,7 @@ impl<Block: BlockT> client::blockchain::Backend<Block> for BlockchainDb<Block> {
Ok(self.meta.read().finalized_hash.clone())
}

fn cache(&self) -> Option<&client::blockchain::Cache<Block>> {
fn cache(&self) -> Option<Arc<client::blockchain::Cache<Block>>> {
None
}

Expand All @@ -256,6 +257,12 @@ impl<Block: BlockT> client::blockchain::Backend<Block> for BlockchainDb<Block> {
}
}

impl<Block: BlockT> client::blockchain::ProvideCache<Block> for BlockchainDb<Block> {
fn cache(&self) -> Option<Arc<client::blockchain::Cache<Block>>> {
None
}
}

/// Database transaction
pub struct BlockImportOperation<Block: BlockT, H: Hasher> {
old_state: CachingState<Blake2Hasher, DbState, Block>,
Expand Down Expand Up @@ -306,8 +313,8 @@ where Block: BlockT<Hash=H256>,
Ok(())
}

fn update_authorities(&mut self, _authorities: Vec<AuthorityIdFor<Block>>) {
// currently authorities are not cached on full nodes
fn update_cache(&mut self, _cache: HashMap<Vec<u8>, Vec<u8>>) {
// Currently cache isn't implemented on full nodes.
}

fn update_db_storage(&mut self, update: PrefixedMemoryDB<Blake2Hasher>) -> Result<(), client::error::Error> {
Expand Down
Loading