mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 21:11:07 +00:00
Move authorities interface from Core to consensus (#1412)
* Move authorities interface from Core to consensus f * notify all caches of block insert + create with up-to-date best_fin * merged authorities_are_cached from light_grandpa_import2 * Add ProvideCache trait * Create helper function for 'get_cache' * Fix some formatting * Bump impl version * Resolve wasm conflicts * Apply review comments * Use try_for_each * Move authorities interface from Core to consensus f * notify all caches of block insert + create with up-to-date best_fin * merged authorities_are_cached from light_grandpa_import2 * Add ProvideCache trait * Create helper function for 'get_cache' * Fix some formatting * Bump impl version * Resolve wasm conflicts * Apply review comments * Use try_for_each * Move authorities interface from Core to consensus f * notify all caches of block insert + create with up-to-date best_fin * merged authorities_are_cached from light_grandpa_import2 * Add ProvideCache trait * Create helper function for 'get_cache' * Fix some formatting * Bump impl version * Resolve wasm conflicts * Apply review comments * Use try_for_each * Increment impl_version * Update lib.rs
This commit is contained in:
committed by
Gav Wood
parent
55788fdf77
commit
cbfc36b39f
@@ -16,10 +16,11 @@
|
||||
|
||||
//! Substrate Client data backend
|
||||
|
||||
use std::collections::HashMap;
|
||||
use crate::error;
|
||||
use primitives::ChangesTrieConfiguration;
|
||||
use runtime_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay};
|
||||
use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, NumberFor};
|
||||
use runtime_primitives::traits::{Block as BlockT, NumberFor};
|
||||
use state_machine::backend::Backend as StateBackend;
|
||||
use state_machine::ChangesTrieStorage as StateChangesTrieStorage;
|
||||
use hash_db::Hasher;
|
||||
@@ -73,9 +74,8 @@ pub trait BlockImportOperation<Block, H> where
|
||||
state: NewBlockState,
|
||||
) -> error::Result<()>;
|
||||
|
||||
/// Append authorities set to the transaction. This is a set of parent block (set which
|
||||
/// has been used to check justification of this block).
|
||||
fn update_authorities(&mut self, authorities: Vec<AuthorityIdFor<Block>>);
|
||||
/// Update cached data.
|
||||
fn update_cache(&mut self, cache: HashMap<Vec<u8>, Vec<u8>>);
|
||||
/// Inject storage data into the database.
|
||||
fn update_db_storage(&mut self, update: <Self::State as StateBackend<H>>::Transaction) -> error::Result<()>;
|
||||
/// Inject storage data into the database replacing any existing data.
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
//! Substrate blockchain trait
|
||||
|
||||
use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, Header as HeaderT, NumberFor};
|
||||
use std::sync::Arc;
|
||||
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::Justification;
|
||||
|
||||
@@ -78,7 +80,7 @@ pub trait Backend<Block: BlockT>: HeaderBackend<Block> {
|
||||
/// Get last finalized block hash.
|
||||
fn last_finalized(&self) -> Result<Block::Hash>;
|
||||
/// Returns data cache reference, if it is enabled on this backend.
|
||||
fn cache(&self) -> Option<&Cache<Block>>;
|
||||
fn cache(&self) -> Option<Arc<Cache<Block>>>;
|
||||
|
||||
/// Returns hashes of all blocks that are leaves of the block tree.
|
||||
/// in other words, that have no children, are chain heads.
|
||||
@@ -89,10 +91,16 @@ pub trait Backend<Block: BlockT>: HeaderBackend<Block> {
|
||||
fn children(&self, parent_hash: Block::Hash) -> Result<Vec<Block::Hash>>;
|
||||
}
|
||||
|
||||
/// Provides access to the optional cache.
|
||||
pub trait ProvideCache<Block: BlockT> {
|
||||
/// Returns data cache reference, if it is enabled on this backend.
|
||||
fn cache(&self) -> Option<Arc<Cache<Block>>>;
|
||||
}
|
||||
|
||||
/// Blockchain optional data cache.
|
||||
pub trait Cache<Block: BlockT>: Send + Sync {
|
||||
/// Returns the set of authorities, that was active at given block or None if there's no entry in the cache.
|
||||
fn authorities_at(&self, block: BlockId<Block>) -> Option<Vec<AuthorityIdFor<Block>>>;
|
||||
/// Returns cached value by the given key.
|
||||
fn get_at(&self, key: &[u8], block: &BlockId<Block>) -> Option<Vec<u8>>;
|
||||
}
|
||||
|
||||
/// Blockchain info
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Substrate Client
|
||||
|
||||
use std::{marker::PhantomData, collections::{HashSet, BTreeMap}, sync::Arc, panic::UnwindSafe, result};
|
||||
use std::{marker::PhantomData, collections::{HashSet, BTreeMap, HashMap}, sync::Arc, panic::UnwindSafe, result};
|
||||
use crate::error::Error;
|
||||
use futures::sync::mpsc;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
@@ -31,7 +31,7 @@ use consensus::{
|
||||
};
|
||||
use runtime_primitives::traits::{
|
||||
Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight, BlockNumberToHash,
|
||||
ApiRef, ProvideRuntimeApi, Digest, DigestItem, AuthorityIdFor
|
||||
ApiRef, ProvideRuntimeApi, Digest, DigestItem
|
||||
};
|
||||
use runtime_primitives::BuildStorage;
|
||||
use crate::runtime_api::{CallRuntimeAt, ConstructRuntimeApi};
|
||||
@@ -49,7 +49,8 @@ use hash_db::Hasher;
|
||||
|
||||
use crate::backend::{self, BlockImportOperation, PrunableStateChangesTrieStorage};
|
||||
use crate::blockchain::{
|
||||
self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend
|
||||
self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend,
|
||||
ProvideCache, Cache,
|
||||
};
|
||||
use crate::call_executor::{CallExecutor, LocalCallExecutor};
|
||||
use executor::{RuntimeVersion, RuntimeInfo};
|
||||
@@ -342,16 +343,6 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
.expect("None is returned if there's no value stored for the given key; ':code' key is always defined; qed").0)
|
||||
}
|
||||
|
||||
/// Get the set of authorities at a given block.
|
||||
pub fn authorities_at(&self, id: &BlockId<Block>) -> error::Result<Vec<AuthorityIdFor<Block>>> {
|
||||
match self.backend.blockchain().cache().and_then(|cache| cache.authorities_at(*id)) {
|
||||
Some(cached_value) => Ok(cached_value),
|
||||
None => self.executor.call(id, "Core_authorities", &[], ExecutionStrategy::NativeElseWasm, NeverOffchainExt::new())
|
||||
.and_then(|r| Vec::<AuthorityIdFor<Block>>::decode(&mut &r[..])
|
||||
.ok_or_else(|| error::ErrorKind::InvalidAuthoritiesSet.into()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the RuntimeVersion at a given block.
|
||||
pub fn runtime_version_at(&self, id: &BlockId<Block>) -> error::Result<RuntimeVersion> {
|
||||
self.executor.runtime_version(id)
|
||||
@@ -681,7 +672,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
&self,
|
||||
operation: &mut ClientImportOperation<Block, Blake2Hasher, B>,
|
||||
import_block: ImportBlock<Block>,
|
||||
new_authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
new_cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
) -> error::Result<ImportResult> where
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone,
|
||||
{
|
||||
@@ -729,7 +720,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
import_headers,
|
||||
justification,
|
||||
body,
|
||||
new_authorities,
|
||||
new_cache,
|
||||
finalized,
|
||||
auxiliary,
|
||||
fork_choice,
|
||||
@@ -752,7 +743,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
import_headers: PrePostHeader<Block::Header>,
|
||||
justification: Option<Justification>,
|
||||
body: Option<Vec<Block::Extrinsic>>,
|
||||
authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
new_cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
finalized: bool,
|
||||
aux: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
fork_choice: ForkChoiceStrategy,
|
||||
@@ -810,9 +801,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
leaf_state,
|
||||
)?;
|
||||
|
||||
if let Some(authorities) = authorities {
|
||||
operation.op.update_authorities(authorities);
|
||||
}
|
||||
operation.op.update_cache(new_cache);
|
||||
if let Some(storage_update) = storage_update {
|
||||
operation.op.update_db_storage(storage_update)?;
|
||||
}
|
||||
@@ -1324,6 +1313,15 @@ impl<B, E, Block, RA> ChainHeaderBackend<Block> for Client<B, E, Block, RA> wher
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block, RA> ProvideCache<Block> for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
Block: BlockT<Hash=H256>,
|
||||
{
|
||||
fn cache(&self) -> Option<Arc<Cache<Block>>> {
|
||||
self.backend.blockchain().cache()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block, RA> ProvideRuntimeApi for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Clone + Send + Sync,
|
||||
@@ -1398,10 +1396,10 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
|
||||
fn import_block(
|
||||
&self,
|
||||
import_block: ImportBlock<Block>,
|
||||
new_authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
new_cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
self.lock_import_and_run(|operation| {
|
||||
self.apply_block(operation, import_block, new_authorities)
|
||||
self.apply_block(operation, import_block, new_cache)
|
||||
}).map_err(|e| ConsensusErrorKind::ClientImport(e.to_string()).into())
|
||||
}
|
||||
|
||||
@@ -1431,17 +1429,6 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block, RA> consensus::Authorities<Block> for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Clone,
|
||||
Block: BlockT<Hash=H256>,
|
||||
{
|
||||
type Error = Error;
|
||||
fn authorities(&self, at: &BlockId<Block>) -> Result<Vec<AuthorityIdFor<Block>>, Self::Error> {
|
||||
self.authorities_at(at).map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block, RA> CurrentHeight for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher>,
|
||||
@@ -1550,7 +1537,7 @@ pub(crate) mod tests {
|
||||
use primitives::twox_128;
|
||||
use runtime_primitives::traits::DigestItem as DigestItemT;
|
||||
use runtime_primitives::generic::DigestItem;
|
||||
use test_client::{self, TestClient, AccountKeyring, AuthorityKeyring};
|
||||
use test_client::{self, TestClient, AccountKeyring};
|
||||
use consensus::BlockOrigin;
|
||||
use test_client::client::backend::Backend as TestBackend;
|
||||
use test_client::BlockBuilderExt;
|
||||
@@ -1649,18 +1636,6 @@ pub(crate) mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authorities_call_works() {
|
||||
let client = test_client::new();
|
||||
|
||||
assert_eq!(client.info().unwrap().chain.best_number, 0);
|
||||
assert_eq!(client.authorities_at(&BlockId::Number(0)).unwrap(), vec![
|
||||
AuthorityKeyring::Alice.into(),
|
||||
AuthorityKeyring::Bob.into(),
|
||||
AuthorityKeyring::Charlie.into()
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_builder_works_with_no_transactions() {
|
||||
let client = test_client::new();
|
||||
@@ -1705,15 +1680,6 @@ pub(crate) mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_uses_authorities_from_blockchain_cache() {
|
||||
let client = test_client::new_light();
|
||||
let genesis_hash = client.header(&BlockId::Number(0)).unwrap().unwrap().hash();
|
||||
// authorities cache is first filled in genesis block
|
||||
// => should be read from cache here (remote request will fail in this test)
|
||||
assert!(!client.authorities_at(&BlockId::Hash(genesis_hash)).unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_builder_does_not_include_invalid() {
|
||||
let client = test_client::new();
|
||||
|
||||
@@ -62,12 +62,6 @@ error_chain! {
|
||||
display("Blockchain: {}", e),
|
||||
}
|
||||
|
||||
/// Invalid authorities set received from the runtime.
|
||||
InvalidAuthoritiesSet {
|
||||
description("authorities set is invalid"),
|
||||
display("Current state of blockchain has invalid authorities set"),
|
||||
}
|
||||
|
||||
/// Could not get runtime version.
|
||||
VersionInvalid {
|
||||
description("Runtime version error"),
|
||||
|
||||
@@ -22,7 +22,7 @@ use parking_lot::RwLock;
|
||||
use primitives::{ChangesTrieConfiguration, storage::well_known_keys};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero,
|
||||
NumberFor, As, Digest, DigestItem, AuthorityIdFor};
|
||||
NumberFor, As, Digest, DigestItem};
|
||||
use runtime_primitives::{Justification, StorageOverlay, ChildrenStorageOverlay};
|
||||
use state_machine::backend::{Backend as StateBackend, InMemory, Consolidate};
|
||||
use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId};
|
||||
@@ -104,12 +104,6 @@ struct BlockchainStorage<Block: BlockT> {
|
||||
/// In-memory blockchain. Supports concurrent reads.
|
||||
pub struct Blockchain<Block: BlockT> {
|
||||
storage: Arc<RwLock<BlockchainStorage<Block>>>,
|
||||
cache: Cache<Block>,
|
||||
}
|
||||
|
||||
struct Cache<Block: BlockT> {
|
||||
storage: Arc<RwLock<BlockchainStorage<Block>>>,
|
||||
authorities_at: RwLock<HashMap<Block::Hash, Option<Vec<AuthorityIdFor<Block>>>>>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT + Clone> Clone for Blockchain<Block> {
|
||||
@@ -117,10 +111,6 @@ impl<Block: BlockT + Clone> Clone for Blockchain<Block> {
|
||||
let storage = Arc::new(RwLock::new(self.storage.read().clone()));
|
||||
Blockchain {
|
||||
storage: storage.clone(),
|
||||
cache: Cache {
|
||||
storage,
|
||||
authorities_at: RwLock::new(self.cache.authorities_at.read().clone()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,10 +142,6 @@ impl<Block: BlockT> Blockchain<Block> {
|
||||
}));
|
||||
Blockchain {
|
||||
storage: storage.clone(),
|
||||
cache: Cache {
|
||||
storage: storage,
|
||||
authorities_at: Default::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,8 +341,8 @@ impl<Block: BlockT> blockchain::Backend<Block> for Blockchain<Block> {
|
||||
Ok(self.storage.read().finalized_hash.clone())
|
||||
}
|
||||
|
||||
fn cache(&self) -> Option<&blockchain::Cache<Block>> {
|
||||
Some(&self.cache)
|
||||
fn cache(&self) -> Option<Arc<blockchain::Cache<Block>>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn leaves(&self) -> error::Result<Vec<Block::Hash>> {
|
||||
@@ -368,6 +354,12 @@ impl<Block: BlockT> blockchain::Backend<Block> for Blockchain<Block> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT> blockchain::ProvideCache<Block> for Blockchain<Block> {
|
||||
fn cache(&self) -> Option<Arc<blockchain::Cache<Block>>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT> backend::AuxStore for Blockchain<Block> {
|
||||
fn insert_aux<
|
||||
'a,
|
||||
@@ -398,16 +390,12 @@ impl<Block: BlockT> light::blockchain::Storage<Block> for Blockchain<Block>
|
||||
fn import_header(
|
||||
&self,
|
||||
header: Block::Header,
|
||||
authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
_cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
state: NewBlockState,
|
||||
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
) -> error::Result<()> {
|
||||
let hash = header.hash();
|
||||
let parent_hash = *header.parent_hash();
|
||||
self.insert(hash, header, None, None, state)?;
|
||||
if state.is_best() {
|
||||
self.cache.insert(parent_hash, authorities);
|
||||
}
|
||||
|
||||
self.write_aux(aux_ops);
|
||||
Ok(())
|
||||
@@ -435,15 +423,15 @@ impl<Block: BlockT> light::blockchain::Storage<Block> for Blockchain<Block>
|
||||
.ok_or_else(|| error::ErrorKind::Backend(format!("Changes trie CHT for block {} not exists", block)).into())
|
||||
}
|
||||
|
||||
fn cache(&self) -> Option<&blockchain::Cache<Block>> {
|
||||
Some(&self.cache)
|
||||
fn cache(&self) -> Option<Arc<blockchain::Cache<Block>>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// In-memory operation.
|
||||
pub struct BlockImportOperation<Block: BlockT, H: Hasher> {
|
||||
pending_block: Option<PendingBlock<Block>>,
|
||||
pending_authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
pending_cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
old_state: InMemory<H>,
|
||||
new_state: Option<InMemory<H>>,
|
||||
changes_trie_update: Option<MemoryDB<H>>,
|
||||
@@ -480,8 +468,8 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_authorities(&mut self, authorities: Vec<AuthorityIdFor<Block>>) {
|
||||
self.pending_authorities = Some(authorities);
|
||||
fn update_cache(&mut self, cache: HashMap<Vec<u8>, Vec<u8>>) {
|
||||
self.pending_cache = cache;
|
||||
}
|
||||
|
||||
fn update_db_storage(&mut self, update: <InMemory<H> as StateBackend<H>>::Transaction) -> error::Result<()> {
|
||||
@@ -602,7 +590,7 @@ where
|
||||
let old_state = self.state_at(BlockId::Hash(Default::default()))?;
|
||||
Ok(BlockImportOperation {
|
||||
pending_block: None,
|
||||
pending_authorities: None,
|
||||
pending_cache: Default::default(),
|
||||
old_state,
|
||||
new_state: None,
|
||||
changes_trie_update: None,
|
||||
@@ -629,7 +617,6 @@ where
|
||||
let (header, body, justification) = pending_block.block.into_inner();
|
||||
|
||||
let hash = header.hash();
|
||||
let parent_hash = *header.parent_hash();
|
||||
|
||||
self.states.write().insert(hash, operation.new_state.unwrap_or_else(|| old_state.clone()));
|
||||
|
||||
@@ -642,10 +629,6 @@ where
|
||||
}
|
||||
|
||||
self.blockchain.insert(hash, header, justification, body, pending_block.state)?;
|
||||
// dumb implementation - store value for each block
|
||||
if pending_block.state.is_best() {
|
||||
self.blockchain.cache.insert(parent_hash, operation.pending_authorities);
|
||||
}
|
||||
}
|
||||
|
||||
if !operation.aux.is_empty() {
|
||||
@@ -710,23 +693,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT> Cache<Block> {
|
||||
fn insert(&self, at: Block::Hash, authorities: Option<Vec<AuthorityIdFor<Block>>>) {
|
||||
self.authorities_at.write().insert(at, authorities);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT> blockchain::Cache<Block> for Cache<Block> {
|
||||
fn authorities_at(&self, block: BlockId<Block>) -> Option<Vec<AuthorityIdFor<Block>>> {
|
||||
let hash = match block {
|
||||
BlockId::Hash(hash) => hash,
|
||||
BlockId::Number(number) => self.storage.read().hashes.get(&number).cloned()?,
|
||||
};
|
||||
|
||||
self.authorities_at.read().get(&hash).cloned().unwrap_or(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Prunable in-memory changes trie storage.
|
||||
pub struct ChangesTrieStorage<H: Hasher>(InMemoryChangesTrieStorage<H>) where H::Out: HeapSizeOf;
|
||||
impl<H: Hasher> backend::PrunableStateChangesTrieStorage<H> for ChangesTrieStorage<H> where H::Out: HeapSizeOf {
|
||||
@@ -747,15 +713,6 @@ impl<H: Hasher> state_machine::ChangesTrieStorage<H> for ChangesTrieStorage<H> w
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert authorities entry into in-memory blockchain cache. Extracted as a separate function to use it in tests.
|
||||
pub fn cache_authorities_at<Block: BlockT>(
|
||||
blockchain: &Blockchain<Block>,
|
||||
at: Block::Hash,
|
||||
authorities: Option<Vec<AuthorityIdFor<Block>>>
|
||||
) {
|
||||
blockchain.cache.insert(at, authorities);
|
||||
}
|
||||
|
||||
/// Check that genesis storage is valid.
|
||||
pub fn check_genesis_storage(top: &StorageOverlay, children: &ChildrenStorageOverlay) -> error::Result<()> {
|
||||
if top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) {
|
||||
|
||||
@@ -24,7 +24,7 @@ use parking_lot::RwLock;
|
||||
|
||||
use runtime_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay};
|
||||
use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState};
|
||||
use runtime_primitives::traits::{Block as BlockT, NumberFor, AuthorityIdFor, Zero, Header};
|
||||
use runtime_primitives::traits::{Block as BlockT, NumberFor, Zero, Header};
|
||||
use crate::in_mem::{self, check_genesis_storage};
|
||||
use crate::backend::{AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState};
|
||||
use crate::blockchain::HeaderBackend as BlockchainHeaderBackend;
|
||||
@@ -46,7 +46,7 @@ pub struct Backend<S, F, H> {
|
||||
/// Light block (header and justification) import operation.
|
||||
pub struct ImportOperation<Block: BlockT, S, F, H> {
|
||||
header: Option<Block::Header>,
|
||||
authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
leaf_state: NewBlockState,
|
||||
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
finalized_blocks: Vec<BlockId<Block>>,
|
||||
@@ -117,7 +117,7 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F, H> where
|
||||
fn begin_operation(&self) -> ClientResult<Self::BlockImportOperation> {
|
||||
Ok(ImportOperation {
|
||||
header: None,
|
||||
authorities: None,
|
||||
cache: Default::default(),
|
||||
leaf_state: NewBlockState::Normal,
|
||||
aux_ops: Vec::new(),
|
||||
finalized_blocks: Vec::new(),
|
||||
@@ -146,7 +146,7 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F, H> where
|
||||
let is_genesis_import = header.number().is_zero();
|
||||
self.blockchain.storage().import_header(
|
||||
header,
|
||||
operation.authorities,
|
||||
operation.cache,
|
||||
operation.leaf_state,
|
||||
operation.aux_ops,
|
||||
)?;
|
||||
@@ -254,8 +254,8 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_authorities(&mut self, authorities: Vec<AuthorityIdFor<Block>>) {
|
||||
self.authorities = Some(authorities);
|
||||
fn update_cache(&mut self, cache: HashMap<Vec<u8>, Vec<u8>>) {
|
||||
self.cache = cache;
|
||||
}
|
||||
|
||||
fn update_db_storage(&mut self, _update: <Self::State as StateBackend<H>>::Transaction) -> ClientResult<()> {
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
//! Light client blockchin backend. Only stores headers and justifications of recent
|
||||
//! blocks. CHT roots are stored for headers of ancient blocks.
|
||||
|
||||
use std::sync::Weak;
|
||||
use std::{sync::{Weak, Arc}, collections::HashMap};
|
||||
use futures::{Future, IntoFuture};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use runtime_primitives::{Justification, generic::BlockId};
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero, AuthorityIdFor};
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero};
|
||||
|
||||
use crate::backend::{AuxStore, NewBlockState};
|
||||
use crate::blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache,
|
||||
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo};
|
||||
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache};
|
||||
use crate::cht;
|
||||
use crate::error::{ErrorKind as ClientErrorKind, Result as ClientResult};
|
||||
use crate::light::fetcher::{Fetcher, RemoteHeaderRequest};
|
||||
@@ -40,7 +40,7 @@ pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> {
|
||||
fn import_header(
|
||||
&self,
|
||||
header: Block::Header,
|
||||
authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
state: NewBlockState,
|
||||
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
) -> ClientResult<()>;
|
||||
@@ -61,7 +61,7 @@ pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> {
|
||||
fn changes_trie_cht_root(&self, cht_size: u64, block: NumberFor<Block>) -> ClientResult<Block::Hash>;
|
||||
|
||||
/// Get storage cache.
|
||||
fn cache(&self) -> Option<&BlockchainCache<Block>>;
|
||||
fn cache(&self) -> Option<Arc<BlockchainCache<Block>>>;
|
||||
}
|
||||
|
||||
/// Light client blockchain.
|
||||
@@ -156,7 +156,7 @@ impl<S, F, Block> BlockchainBackend<Block> for Blockchain<S, F> where Block: Blo
|
||||
self.storage.last_finalized()
|
||||
}
|
||||
|
||||
fn cache(&self) -> Option<&BlockchainCache<Block>> {
|
||||
fn cache(&self) -> Option<Arc<BlockchainCache<Block>>> {
|
||||
self.storage.cache()
|
||||
}
|
||||
|
||||
@@ -169,6 +169,12 @@ impl<S, F, Block> BlockchainBackend<Block> for Blockchain<S, F> where Block: Blo
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Storage<Block>, F, Block: BlockT> ProvideCache<Block> for Blockchain<S, F> {
|
||||
fn cache(&self) -> Option<Arc<BlockchainCache<Block>>> {
|
||||
self.storage.cache()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use std::collections::HashMap;
|
||||
@@ -246,7 +252,7 @@ pub mod tests {
|
||||
fn import_header(
|
||||
&self,
|
||||
_header: Header,
|
||||
_authorities: Option<Vec<AuthorityIdFor<Block>>>,
|
||||
_cache: HashMap<Vec<u8>, Vec<u8>>,
|
||||
_state: NewBlockState,
|
||||
_aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
) -> ClientResult<()> {
|
||||
@@ -278,7 +284,7 @@ pub mod tests {
|
||||
).into())
|
||||
}
|
||||
|
||||
fn cache(&self) -> Option<&BlockchainCache<Block>> {
|
||||
fn cache(&self) -> Option<Arc<BlockchainCache<Block>>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// check method that doesn't requires environment
|
||||
let (remote, local) = execute(&remote_client, 0, "Core_authorities");
|
||||
let (remote, local) = execute(&remote_client, 0, "Core_version");
|
||||
assert_eq!(remote, local);
|
||||
|
||||
// check method that requires environment
|
||||
|
||||
@@ -390,6 +390,7 @@ impl<'a, H, Number, Hash> ChangesTrieRootsStorage<H> for RootsStorage<'a, Number
|
||||
pub mod tests {
|
||||
use futures::future::{ok, err, FutureResult};
|
||||
use parking_lot::Mutex;
|
||||
use parity_codec::Decode;
|
||||
use crate::client::tests::prepare_client_with_key_changes;
|
||||
use executor::{self, NativeExecutionDispatch};
|
||||
use crate::error::Error as ClientError;
|
||||
@@ -436,7 +437,7 @@ pub mod tests {
|
||||
|
||||
type TestChecker = LightDataChecker<executor::NativeExecutor<test_client::LocalExecutor>, Blake2Hasher, Block, DummyStorage, OkCallFetcher>;
|
||||
|
||||
fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec<Vec<u8>>, usize) {
|
||||
fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec<Vec<u8>>, u32) {
|
||||
// prepare remote client
|
||||
let remote_client = test_client::new();
|
||||
let remote_block_id = BlockId::Number(0);
|
||||
@@ -445,7 +446,9 @@ pub mod tests {
|
||||
remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap().storage_root(::std::iter::empty()).0.into();
|
||||
|
||||
// 'fetch' read proof from remote node
|
||||
let authorities_len = remote_client.authorities_at(&remote_block_id).unwrap().len();
|
||||
let authorities_len = remote_client.storage(&remote_block_id, &StorageKey(well_known_keys::AUTHORITY_COUNT.to_vec()))
|
||||
.unwrap()
|
||||
.and_then(|v| Decode::decode(&mut &v.0[..])).unwrap();
|
||||
let remote_read_proof = remote_client.read_proof(&remote_block_id, well_known_keys::AUTHORITY_COUNT).unwrap();
|
||||
|
||||
// check remote read proof locally
|
||||
|
||||
@@ -38,7 +38,6 @@ use rstd::result;
|
||||
pub use parity_codec::{Encode, Decode};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::error;
|
||||
use rstd::vec::Vec;
|
||||
use sr_api_macros::decl_runtime_apis;
|
||||
use primitives::OpaqueMetadata;
|
||||
#[cfg(feature = "std")]
|
||||
@@ -112,13 +111,11 @@ pub trait CallRuntimeAt<Block: BlockT> {
|
||||
}
|
||||
|
||||
decl_runtime_apis! {
|
||||
/// The `Core` api trait that is mandantory for each runtime.
|
||||
/// The `Core` api trait that is mandatory for each runtime.
|
||||
#[core_trait]
|
||||
pub trait Core {
|
||||
/// Returns the version of the runtime.
|
||||
fn version() -> RuntimeVersion;
|
||||
/// Returns the authorities.
|
||||
fn authorities() -> Vec<AuthorityIdFor<Block>>;
|
||||
/// Execute the given block.
|
||||
fn execute_block(block: Block);
|
||||
/// Initialize a block with the given header.
|
||||
|
||||
Reference in New Issue
Block a user