Optimize tree route to sync faster (#3665)

* Introduce HeaderMetadata and use it for tree_route. Add lowest_common_ancestor.
* Add tests.
This commit is contained in:
Marcio Diaz
2019-10-02 20:30:43 +02:00
committed by GitHub
parent 8646cd158e
commit f6bd58ac1f
22 changed files with 677 additions and 280 deletions
+31 -2
View File
@@ -23,18 +23,20 @@ use std::{sync::Arc, collections::HashMap};
use sr_primitives::{Justification, generic::BlockId};
use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero};
use header_metadata::{HeaderMetadata, CachedHeaderMetadata};
use crate::backend::{AuxStore, NewBlockState};
use crate::blockchain::{
Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache,
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache,
well_known_cache_keys,
well_known_cache_keys
};
use crate::cht;
use crate::error::{Error as ClientError, Result as ClientResult};
use crate::light::fetcher::{Fetcher, RemoteHeaderRequest};
/// Light client blockchain storage.
pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> {
pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> + HeaderMetadata<Block, Error=ClientError> {
/// Store new header. Should refuse to revert any finalized blocks.
///
/// Takes new authorities, the leaf state of the new block, and
@@ -140,6 +142,22 @@ impl<S, Block> BlockchainHeaderBackend<Block> for Blockchain<S> where Block: Blo
}
}
impl<S, Block> HeaderMetadata<Block> for Blockchain<S> where Block: BlockT, S: Storage<Block> {
type Error = ClientError;
fn header_metadata(&self, hash: Block::Hash) -> Result<CachedHeaderMetadata<Block>, Self::Error> {
self.storage.header_metadata(hash)
}
fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata<Block>) {
self.storage.insert_header_metadata(hash, metadata)
}
fn remove_header_metadata(&self, hash: Block::Hash) {
self.storage.remove_header_metadata(hash)
}
}
impl<S, Block> BlockchainBackend<Block> for Blockchain<S> where Block: BlockT, S: Storage<Block> {
fn body(&self, _id: BlockId<Block>) -> ClientResult<Option<Vec<Block::Extrinsic>>> {
Err(ClientError::NotAvailableOnLightClient)
@@ -281,6 +299,17 @@ pub mod tests {
}
}
impl HeaderMetadata<Block> for DummyStorage {
type Error = ClientError;
fn header_metadata(&self, hash: Hash) -> Result<CachedHeaderMetadata<Block>, Self::Error> {
self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header))
.ok_or(ClientError::UnknownBlock("header not found".to_owned()))
}
fn insert_header_metadata(&self, _hash: Hash, _metadata: CachedHeaderMetadata<Block>) {}
fn remove_header_metadata(&self, _hash: Hash) {}
}
impl AuxStore for DummyStorage {
fn insert_aux<
'a,