Atomic operation and locking when importing a block (#1489)

* Add ClientImportOperation and remove an unused enum

* set_aux to insert_aux so that it can be called multiple times

* [WIP] All basic designs of lock_import_and_run

* [WIP] `apply_block` and `apply_aux` implementation

* Update client db with the new interface

* Always make sure we reset importing_block back to None

* Address grumbles

`apply_block` should be pub

* Add comments on insert_aux

* Fix compile
This commit is contained in:
Wei Tang
2019-01-24 16:51:53 +01:00
committed by Gav Wood
parent 7f05bd959f
commit 997c8b4020
6 changed files with 380 additions and 190 deletions
+35 -11
View File
@@ -45,6 +45,7 @@ pub struct ImportOperation<Block: BlockT, S, F> {
authorities: Option<Vec<AuthorityIdFor<Block>>>,
leaf_state: NewBlockState,
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
finalized_blocks: Vec<BlockId<Block>>,
_phantom: ::std::marker::PhantomData<(S, F)>,
}
@@ -96,24 +97,42 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F> where
type State = OnDemandState<Block, S, F>;
type ChangesTrieStorage = in_mem::ChangesTrieStorage<H>;
fn begin_operation(&self, _block: BlockId<Block>) -> ClientResult<Self::BlockImportOperation> {
fn begin_operation(&self) -> ClientResult<Self::BlockImportOperation> {
Ok(ImportOperation {
header: None,
authorities: None,
leaf_state: NewBlockState::Normal,
aux_ops: Vec::new(),
finalized_blocks: Vec::new(),
_phantom: Default::default(),
})
}
fn begin_state_operation(
&self,
_operation: &mut Self::BlockImportOperation,
_block: BlockId<Block>
) -> ClientResult<()> {
Ok(())
}
fn commit_operation(&self, operation: Self::BlockImportOperation) -> ClientResult<()> {
let header = operation.header.expect("commit is called after set_block_data; set_block_data sets header; qed");
self.blockchain.storage().import_header(
header,
operation.authorities,
operation.leaf_state,
operation.aux_ops,
)
if !operation.finalized_blocks.is_empty() {
for block in operation.finalized_blocks {
self.blockchain.storage().finalize_header(block)?;
}
}
if let Some(header) = operation.header {
self.blockchain.storage().import_header(
header,
operation.authorities,
operation.leaf_state,
operation.aux_ops,
)?;
}
Ok(())
}
fn finalize_block(&self, block: BlockId<Block>, _justification: Option<Justification>) -> ClientResult<()> {
@@ -199,14 +218,14 @@ where
fn reset_storage(&mut self, top: StorageMap, children: ChildrenStorageMap) -> ClientResult<H::Out> {
let in_mem = in_mem::Backend::<Block, H>::new();
let mut op = in_mem.begin_operation(BlockId::Hash(Default::default()))?;
let mut op = in_mem.begin_operation()?;
op.reset_storage(top, children)
}
fn set_aux<I>(&mut self, ops: I) -> ClientResult<()>
fn insert_aux<I>(&mut self, ops: I) -> ClientResult<()>
where I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
{
self.aux_ops = ops.into_iter().collect();
self.aux_ops.append(&mut ops.into_iter().collect());
Ok(())
}
@@ -214,6 +233,11 @@ where
// we're not storing anything locally => ignore changes
Ok(())
}
fn mark_finalized(&mut self, block: BlockId<Block>, _justification: Option<Justification>) -> ClientResult<()> {
self.finalized_blocks.push(block);
Ok(())
}
}
impl<Block, S, F, H> StateBackend<H> for OnDemandState<Block, S, F>