Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Make light client backend only work with locally available data (#3538)
Browse files Browse the repository at this point in the history
* removing fetcher dependency from light backend

* fix compilation
  • Loading branch information
svyatonik authored and gavofyork committed Sep 12, 2019
1 parent a0dd5e8 commit 8426cf1
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 560 deletions.
232 changes: 57 additions & 175 deletions core/client/src/light/backend.rs

Large diffs are not rendered by default.

55 changes: 15 additions & 40 deletions core/client/src/light/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
//! blocks. CHT roots are stored for headers of ancient blocks.
use std::future::Future;
use std::{sync::{Weak, Arc}, collections::HashMap};
use parking_lot::Mutex;
use std::{sync::Arc, collections::HashMap};

use sr_primitives::{Justification, generic::BlockId};
use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero};
Expand All @@ -30,7 +29,7 @@ use crate::blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as Bloc
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache};
use crate::cht;
use crate::error::{Error as ClientError, Result as ClientResult};
use crate::light::fetcher::{Fetcher, RemoteBodyRequest, RemoteHeaderRequest};
use crate::light::fetcher::{Fetcher, RemoteHeaderRequest};

/// Light client blockchain storage.
pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> {
Expand Down Expand Up @@ -95,37 +94,25 @@ pub trait RemoteBlockchain<Block: BlockT>: Send + Sync {
}

/// Light client blockchain.
pub struct Blockchain<S, F> {
fetcher: Mutex<Weak<F>>,
pub struct Blockchain<S> {
storage: S,
}

impl<S, F> Blockchain<S, F> {
impl<S> Blockchain<S> {
/// Create new light blockchain backed with given storage.
pub fn new(storage: S) -> Self {
Self {
fetcher: Mutex::new(Default::default()),
storage,
}
}

/// Sets fetcher reference.
pub fn set_fetcher(&self, fetcher: Weak<F>) {
*self.fetcher.lock() = fetcher;
}

/// Get fetcher weak reference.
pub fn fetcher(&self) -> Weak<F> {
self.fetcher.lock().clone()
}

/// Get storage reference.
pub fn storage(&self) -> &S {
&self.storage
}
}

impl<S, F, Block> BlockchainHeaderBackend<Block> for Blockchain<S, F> where Block: BlockT, S: Storage<Block>, F: Fetcher<Block> {
impl<S, Block> BlockchainHeaderBackend<Block> for Blockchain<S> where Block: BlockT, S: Storage<Block> {
fn header(&self, id: BlockId<Block>) -> ClientResult<Option<Block::Header>> {
match RemoteBlockchain::header(self, id)? {
LocalOrRemote::Local(header) => Ok(Some(header)),
Expand All @@ -151,24 +138,13 @@ impl<S, F, Block> BlockchainHeaderBackend<Block> for Blockchain<S, F> where Bloc
}
}

impl<S, F, Block> BlockchainBackend<Block> for Blockchain<S, F> where Block: BlockT, S: Storage<Block>, F: Fetcher<Block> {
fn body(&self, id: BlockId<Block>) -> ClientResult<Option<Vec<Block::Extrinsic>>> {
let header = match BlockchainHeaderBackend::header(self, id)? {
Some(header) => header,
None => return Ok(None),
};

futures03::executor::block_on(
self.fetcher().upgrade().ok_or(ClientError::NotAvailableOnLightClient)?
.remote_body(RemoteBodyRequest {
header,
retry_count: None,
})
).map(Some)
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)
}

fn justification(&self, _id: BlockId<Block>) -> ClientResult<Option<Justification>> {
Ok(None)
Err(ClientError::NotAvailableOnLightClient)
}

fn last_finalized(&self) -> ClientResult<Block::Hash> {
Expand All @@ -180,24 +156,23 @@ impl<S, F, Block> BlockchainBackend<Block> for Blockchain<S, F> where Block: Blo
}

fn leaves(&self) -> ClientResult<Vec<Block::Hash>> {
unimplemented!()
Err(ClientError::NotAvailableOnLightClient)
}

fn children(&self, _parent_hash: Block::Hash) -> ClientResult<Vec<Block::Hash>> {
unimplemented!()
Err(ClientError::NotAvailableOnLightClient)
}
}

impl<S: Storage<Block>, F, Block: BlockT> ProvideCache<Block> for Blockchain<S, F> {
impl<S: Storage<Block>, Block: BlockT> ProvideCache<Block> for Blockchain<S> {
fn cache(&self) -> Option<Arc<dyn BlockchainCache<Block>>> {
self.storage.cache()
}
}

impl<S, F, Block: BlockT> RemoteBlockchain<Block> for Blockchain<S, F>
impl<S, Block: BlockT> RemoteBlockchain<Block> for Blockchain<S>
where
S: Storage<Block>,
F: Fetcher<Block> + Send + Sync,
{
fn header(&self, id: BlockId<Block>) -> ClientResult<LocalOrRemote<
Block::Header,
Expand Down Expand Up @@ -253,12 +228,12 @@ pub fn future_header<Block: BlockT, F: Fetcher<Block>>(
#[cfg(test)]
pub mod tests {
use std::collections::HashMap;
use parking_lot::Mutex;
use test_client::runtime::{Hash, Block, Header};
use crate::blockchain::Info;
use crate::light::fetcher::tests::OkCallFetcher;
use super::*;

pub type DummyBlockchain = Blockchain<DummyStorage, OkCallFetcher>;
pub type DummyBlockchain = Blockchain<DummyStorage>;

pub struct DummyStorage {
pub changes_tries_cht_roots: HashMap<u64, Hash>,
Expand Down
Loading

0 comments on commit 8426cf1

Please sign in to comment.