Move import lock onto backend (#2797)

* Drop import_lock from client, move it into backend, impl default version via static mutex

* still need to allow depcretion because of client.backend

* additional docs

* Remove default impl of get_import_lock, impl on instances

* Bump parking_lot to 0.8.0 accross the board
This commit is contained in:
Benjamin Kampmann
2019-06-05 15:46:01 +02:00
committed by Bastian Köcher
parent 4f888f34d3
commit eaa0ab014a
37 changed files with 101 additions and 97 deletions
+8
View File
@@ -26,6 +26,7 @@ use state_machine::ChangesTrieStorage as StateChangesTrieStorage;
use consensus::well_known_cache_keys;
use hash_db::Hasher;
use trie::MemoryDB;
use parking_lot::Mutex;
/// State of a new block.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -174,6 +175,13 @@ pub trait Backend<Block, H>: AuxStore + Send + Sync where
fn get_aux(&self, key: &[u8]) -> error::Result<Option<Vec<u8>>> {
AuxStore::get_aux(self, key)
}
/// Gain access to the import lock around this backend.
/// _Note_ Backend isn't expected to acquire the lock by itself ever. Rather
/// the using components should acquire and hold the lock whenever they do
/// something that the import of a block would interfere with, e.g. importing
/// a new block or calculating the best head.
fn get_import_lock(&self) -> &Mutex<()>;
}
/// Changes trie storage that supports pruning.
+3 -18
View File
@@ -124,7 +124,6 @@ pub struct Client<B, E, Block, RA> where Block: BlockT {
storage_notifications: Mutex<StorageNotifications<Block>>,
import_notification_sinks: Mutex<Vec<mpsc::UnboundedSender<BlockImportNotification<Block>>>>,
finality_notification_sinks: Mutex<Vec<mpsc::UnboundedSender<FinalityNotification<Block>>>>,
import_lock: Arc<Mutex<()>>,
// holds the block hash currently being imported. TODO: replace this with block queue
importing_block: RwLock<Option<Block::Hash>>,
execution_strategies: ExecutionStrategies,
@@ -318,7 +317,6 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
storage_notifications: Default::default(),
import_notification_sinks: Default::default(),
finality_notification_sinks: Default::default(),
import_lock: Default::default(),
importing_block: Default::default(),
execution_strategies,
_phantom: Default::default(),
@@ -344,15 +342,6 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
&self.backend
}
/// Expose reference to import lock
#[doc(hidden)]
#[deprecated(note="Rather than relying on `client` to provide this, access \
to the backend should be handled at setup only - see #1134. This function \
will be removed once that is in place.")]
pub fn import_lock(&self) -> Arc<Mutex<()>> {
self.import_lock.clone()
}
/// Given a `BlockId` and a key prefix, return the matching child storage keys in that block.
pub fn storage_keys(&self, id: &BlockId<Block>, key_prefix: &StorageKey) -> error::Result<Vec<StorageKey>> {
let keys = self.state_at(id)?.keys(&key_prefix.0).into_iter().map(StorageKey).collect();
@@ -744,7 +733,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
Err: From<error::Error>,
{
let inner = || {
let _import_lock = self.import_lock.lock();
let _import_lock = self.backend.get_import_lock().lock();
let mut op = ClientImportOperation {
op: self.backend.begin_operation()?,
@@ -1493,17 +1482,14 @@ where
/// where 'longest' is defined as the highest number of blocks
pub struct LongestChain<B, Block> {
backend: Arc<B>,
import_lock: Arc<Mutex<()>>,
_phantom: PhantomData<Block>
}
impl<B, Block> Clone for LongestChain<B, Block> {
fn clone(&self) -> Self {
let backend = self.backend.clone();
let import_lock = self.import_lock.clone();
LongestChain {
backend,
import_lock,
_phantom: Default::default()
}
}
@@ -1515,10 +1501,9 @@ where
Block: BlockT<Hash=H256>,
{
/// Instantiate a new LongestChain for Backend B
pub fn new(backend: Arc<B>, import_lock: Arc<Mutex<()>>) -> Self {
pub fn new(backend: Arc<B>) -> Self {
LongestChain {
backend,
import_lock,
_phantom: Default::default()
}
}
@@ -1564,7 +1549,7 @@ where
// ensure no blocks are imported during this code block.
// an import could trigger a reorg which could change the canonical chain.
// we depend on the canonical chain staying the same during this code block.
let _import_lock = self.import_lock.lock();
let _import_lock = self.backend.get_import_lock().lock();
let info = self.backend.blockchain().info();
+7 -1
View File
@@ -18,7 +18,7 @@
use std::collections::HashMap;
use std::sync::Arc;
use parking_lot::RwLock;
use parking_lot::{RwLock, Mutex};
use primitives::{ChangesTrieConfiguration, storage::well_known_keys};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{
@@ -541,6 +541,7 @@ where
states: RwLock<HashMap<Block::Hash, InMemory<H>>>,
changes_trie_storage: ChangesTrieStorage<Block, H>,
blockchain: Blockchain<Block>,
import_lock: Mutex<()>,
}
impl<Block, H> Backend<Block, H>
@@ -555,6 +556,7 @@ where
states: RwLock::new(HashMap::new()),
changes_trie_storage: ChangesTrieStorage(InMemoryChangesTrieStorage::new()),
blockchain: Blockchain::new(),
import_lock: Default::default(),
}
}
}
@@ -684,6 +686,10 @@ where
fn revert(&self, _n: NumberFor<Block>) -> error::Result<NumberFor<Block>> {
Ok(Zero::zero())
}
fn get_import_lock(&self) -> &Mutex<()> {
&self.import_lock
}
}
impl<Block, H> backend::LocalBackend<Block, H> for Backend<Block, H>
+7 -1
View File
@@ -20,7 +20,7 @@
use std::collections::HashMap;
use std::sync::{Arc, Weak};
use futures::{Future, IntoFuture};
use parking_lot::RwLock;
use parking_lot::{RwLock, Mutex};
use runtime_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay};
use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState};
@@ -41,6 +41,7 @@ const IN_MEMORY_EXPECT_PROOF: &str = "InMemory state backend has Void error type
pub struct Backend<S, F, H: Hasher> {
blockchain: Arc<Blockchain<S, F>>,
genesis_state: RwLock<Option<InMemoryState<H>>>,
import_lock: Mutex<()>,
}
/// Light block (header and justification) import operation.
@@ -77,6 +78,7 @@ impl<S, F, H: Hasher> Backend<S, F, H> {
Self {
blockchain,
genesis_state: RwLock::new(None),
import_lock: Default::default(),
}
}
@@ -213,6 +215,10 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F, H> where
fn revert(&self, _n: NumberFor<Block>) -> ClientResult<NumberFor<Block>> {
Err(ClientError::NotAvailableOnLightClient.into())
}
fn get_import_lock(&self) -> &Mutex<()> {
&self.import_lock
}
}
impl<S, F, Block, H> RemoteBackend<Block, H> for Backend<S, F, H>