mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 09:07:57 +00:00
Introduce notion of finality to substrate (#760)
* finalization for in_mem * fetch last finalized block * pruning: use canonical term instead of final * finalize blocks in full node * begin to port light client DB * add tree-route * keep number index consistent in full nodes * fix tests * disable cache and finish porting light client * add AsMut to system module * final leaf is always best * fix all tests * Fix comment and trace * removed unused Into call * add comment on behavior of `finalize_block`
This commit is contained in:
committed by
Gav Wood
parent
28cc4d0fd6
commit
b7d095a2e0
@@ -26,7 +26,7 @@ use runtime_primitives::{bft::Justification, generic::BlockId};
|
||||
use runtime_primitives::traits::{Block as BlockT, NumberFor};
|
||||
use state_machine::{Backend as StateBackend, InMemoryChangesTrieStorage, TrieBackend};
|
||||
|
||||
use backend::{Backend as ClientBackend, BlockImportOperation, RemoteBackend};
|
||||
use backend::{Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState};
|
||||
use blockchain::HeaderBackend as BlockchainHeaderBackend;
|
||||
use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
|
||||
use light::blockchain::{Blockchain, Storage as BlockchainStorage};
|
||||
@@ -43,9 +43,9 @@ pub struct Backend<S, F> {
|
||||
|
||||
/// Light block (header and justification) import operation.
|
||||
pub struct ImportOperation<Block: BlockT, S, F> {
|
||||
is_new_best: bool,
|
||||
header: Option<Block::Header>,
|
||||
authorities: Option<Vec<AuthorityId>>,
|
||||
leaf_state: NewBlockState,
|
||||
_phantom: ::std::marker::PhantomData<(S, F)>,
|
||||
}
|
||||
|
||||
@@ -84,16 +84,24 @@ impl<S, F, Block, H, C> ClientBackend<Block, H, C> for Backend<S, F> where
|
||||
|
||||
fn begin_operation(&self, _block: BlockId<Block>) -> ClientResult<Self::BlockImportOperation> {
|
||||
Ok(ImportOperation {
|
||||
is_new_best: false,
|
||||
header: None,
|
||||
authorities: None,
|
||||
leaf_state: NewBlockState::Normal,
|
||||
_phantom: Default::default(),
|
||||
})
|
||||
}
|
||||
|
||||
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(operation.is_new_best, header, operation.authorities)
|
||||
self.blockchain.storage().import_header(
|
||||
header,
|
||||
operation.authorities,
|
||||
operation.leaf_state,
|
||||
)
|
||||
}
|
||||
|
||||
fn finalize_block(&self, block: BlockId<Block>) -> ClientResult<()> {
|
||||
self.blockchain.storage().finalize_header(block)
|
||||
}
|
||||
|
||||
fn blockchain(&self) -> &Blockchain<S, F> {
|
||||
@@ -153,9 +161,9 @@ where
|
||||
header: Block::Header,
|
||||
_body: Option<Vec<Block::Extrinsic>>,
|
||||
_justification: Option<Justification<Block::Hash>>,
|
||||
is_new_best: bool
|
||||
state: NewBlockState,
|
||||
) -> ClientResult<()> {
|
||||
self.is_new_best = is_new_best;
|
||||
self.leaf_state = state;
|
||||
self.header = Some(header);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ use primitives::AuthorityId;
|
||||
use runtime_primitives::{bft::Justification, generic::BlockId};
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero};
|
||||
|
||||
use backend::NewBlockState;
|
||||
use blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache,
|
||||
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo};
|
||||
use cht;
|
||||
@@ -33,14 +34,20 @@ use light::fetcher::{Fetcher, RemoteHeaderRequest};
|
||||
|
||||
/// Light client blockchain storage.
|
||||
pub trait Storage<Block: BlockT>: BlockchainHeaderBackend<Block> {
|
||||
/// Store new header.
|
||||
/// Store new header. Should refuse to revert any finalized blocks.
|
||||
fn import_header(
|
||||
&self,
|
||||
is_new_best: bool,
|
||||
header: Block::Header,
|
||||
authorities: Option<Vec<AuthorityId>>
|
||||
authorities: Option<Vec<AuthorityId>>,
|
||||
state: NewBlockState,
|
||||
) -> ClientResult<()>;
|
||||
|
||||
/// Mark historic header as finalized.
|
||||
fn finalize_header(&self, block: BlockId<Block>) -> ClientResult<()>;
|
||||
|
||||
/// Get last finalized header.
|
||||
fn last_finalized(&self) -> ClientResult<Block::Hash>;
|
||||
|
||||
/// Get CHT root for given block. Fails if the block is not pruned (not a part of any CHT).
|
||||
fn cht_root(&self, cht_size: u64, block: NumberFor<Block>) -> ClientResult<Block::Hash>;
|
||||
|
||||
@@ -136,6 +143,10 @@ impl<S, F, Block> BlockchainBackend<Block> for Blockchain<S, F> where Block: Blo
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn last_finalized(&self) -> ClientResult<Block::Hash> {
|
||||
self.storage.last_finalized()
|
||||
}
|
||||
|
||||
fn cache(&self) -> Option<&BlockchainCache<Block>> {
|
||||
self.storage.cache()
|
||||
}
|
||||
|
||||
@@ -230,7 +230,13 @@ pub mod tests {
|
||||
|
||||
// check remote read proof locally
|
||||
let local_storage = InMemoryBlockchain::<Block>::new();
|
||||
local_storage.insert(remote_block_hash, remote_block_header.clone(), None, None, true);
|
||||
local_storage.insert(
|
||||
remote_block_hash,
|
||||
remote_block_header.clone(),
|
||||
None,
|
||||
None,
|
||||
::backend::NewBlockState::Final,
|
||||
);
|
||||
let local_executor = test_client::LocalExecutor::new();
|
||||
let local_checker = LightDataChecker::new(local_executor);
|
||||
(local_checker, remote_block_header, remote_read_proof, authorities_len)
|
||||
|
||||
Reference in New Issue
Block a user