Remove BlockNumber <-> u64 conversions from light-client related code (#2666)

* Remove As usage from CHT

* Remove As usage from CHT (continue)

* Restrict BN <-> int conversions in CT

* more BN <-> u64 conversions removed

* upd spec_version

* Apply suggestions from code review

Co-Authored-By: Gavin Wood <github@gavwood.com>

* Apply suggestions from code review

Co-Authored-By: Gavin Wood <github@gavwood.com>

* more grumbles

* fix last grumbles + compilation

* too long lines

* too long lines
This commit is contained in:
Svyatoslav Nikolsky
2019-05-28 16:07:16 +03:00
committed by Gavin Wood
parent 25b88f1a1f
commit 549d9e1da1
41 changed files with 1087 additions and 654 deletions
+1 -1
View File
@@ -112,7 +112,7 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F, H> where
type BlockImportOperation = ImportOperation<Block, S, F, H>;
type Blockchain = Blockchain<S, F>;
type State = OnDemandOrGenesisState<Block, S, F, H>;
type ChangesTrieStorage = in_mem::ChangesTrieStorage<H>;
type ChangesTrieStorage = in_mem::ChangesTrieStorage<Block, H>;
fn begin_operation(&self) -> ClientResult<Self::BlockImportOperation> {
Ok(ImportOperation {
+11 -3
View File
@@ -56,10 +56,18 @@ pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> {
fn last_finalized(&self) -> ClientResult<Block::Hash>;
/// Get headers CHT root for given block. Fails if the block is not pruned (not a part of any CHT).
fn header_cht_root(&self, cht_size: u64, block: NumberFor<Block>) -> ClientResult<Block::Hash>;
fn header_cht_root(
&self,
cht_size: NumberFor<Block>,
block: NumberFor<Block>,
) -> ClientResult<Block::Hash>;
/// Get changes trie CHT root for given block. Fails if the block is not pruned (not a part of any CHT).
fn changes_trie_cht_root(&self, cht_size: u64, block: NumberFor<Block>) -> ClientResult<Block::Hash>;
fn changes_trie_cht_root(
&self,
cht_size: NumberFor<Block>,
block: NumberFor<Block>,
) -> ClientResult<Block::Hash>;
/// Get storage cache.
fn cache(&self) -> Option<Arc<BlockchainCache<Block>>>;
@@ -116,7 +124,7 @@ impl<S, F, Block> BlockchainHeaderBackend<Block> for Blockchain<S, F> where Bloc
self.fetcher().upgrade().ok_or(ClientError::NotAvailableOnLightClient)?
.remote_header(RemoteHeaderRequest {
cht_root: self.storage.header_cht_root(cht::SIZE, number)?,
cht_root: self.storage.header_cht_root(cht::size(), number)?,
block: number,
retry_count: None,
})
@@ -435,7 +435,7 @@ pub fn check_execution_proof<Header, E, H>(
Header: HeaderT,
E: CodeExecutor<H>,
H: Hasher,
H::Out: Ord,
H::Out: Ord + 'static,
{
let local_state_root = request.header.state_root();
let root: H::Out = convert_hash(&local_state_root);
+31 -22
View File
@@ -22,11 +22,11 @@ use std::marker::PhantomData;
use futures::IntoFuture;
use hash_db::{HashDB, Hasher};
use parity_codec::Encode;
use parity_codec::{Decode, Encode};
use primitives::{ChangesTrieConfiguration, convert_hash};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor,
UniqueSaturatedInto, UniqueSaturatedFrom, SaturatedConversion
SimpleArithmetic, CheckedConversion,
};
use state_machine::{CodeExecutor, ChangesTrieRootsStorage, ChangesTrieAnchorBlockId,
TrieBackend, read_proof_check, key_changes_proof_check,
@@ -236,7 +236,7 @@ impl<E, H, B: BlockT, S: BlockchainStorage<B>, F> LightDataChecker<E, H, B, S, F
&self,
request: &RemoteChangesRequest<B::Header>,
remote_proof: ChangesProof<B::Header>,
cht_size: u64,
cht_size: NumberFor<B>,
) -> ClientResult<Vec<(NumberFor<B>, u32)>>
where
H: Hasher,
@@ -284,30 +284,27 @@ impl<E, H, B: BlockT, S: BlockchainStorage<B>, F> LightDataChecker<E, H, B, S, F
}
// and now check the key changes proof + get the changes
key_changes_proof_check::<_, H>(
key_changes_proof_check::<_, H, _>(
&request.changes_trie_config,
&RootsStorage {
roots: (request.tries_roots.0, &request.tries_roots.2),
prev_roots: remote_roots,
},
remote_proof,
request.first_block.0.saturated_into::<u64>(),
request.first_block.0,
&ChangesTrieAnchorBlockId {
hash: convert_hash(&request.last_block.1),
number: request.last_block.0.saturated_into::<u64>(),
number: request.last_block.0,
},
remote_max_block.saturated_into::<u64>(),
remote_max_block,
&request.key)
.map(|pairs| pairs.into_iter().map(|(b, x)|
(b.saturated_into::<NumberFor<B>>(), x)
).collect())
.map_err(|err| ClientError::ChangesTrieAccessFailed(err))
}
/// Check CHT-based proof for changes tries roots.
fn check_changes_tries_proof(
&self,
cht_size: u64,
cht_size: NumberFor<B>,
remote_roots: &BTreeMap<NumberFor<B>, B::Hash>,
remote_roots_proof: Vec<Vec<u8>>,
) -> ClientResult<()>
@@ -363,7 +360,7 @@ impl<E, Block, H, S, F> FetchChecker<Block> for LightDataChecker<E, H, Block, S,
Block: BlockT,
E: CodeExecutor<H>,
H: Hasher,
H::Out: Ord,
H::Out: Ord + 'static,
S: BlockchainStorage<Block>,
F: Send + Sync,
{
@@ -419,7 +416,7 @@ impl<E, Block, H, S, F> FetchChecker<Block> for LightDataChecker<E, H, Block, S,
request: &RemoteChangesRequest<Block::Header>,
remote_proof: ChangesProof<Block::Header>
) -> ClientResult<Vec<(NumberFor<Block>, u32)>> {
self.check_changes_proof_with_cht_size(request, remote_proof, cht::SIZE)
self.check_changes_proof_with_cht_size(request, remote_proof, cht::size())
}
fn check_body_proof(
@@ -443,26 +440,38 @@ impl<E, Block, H, S, F> FetchChecker<Block> for LightDataChecker<E, H, Block, S,
}
/// A view of BTreeMap<Number, Hash> as a changes trie roots storage.
struct RootsStorage<'a, Number: UniqueSaturatedInto<u64> + UniqueSaturatedFrom<u64>, Hash: 'a> {
struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> {
roots: (Number, &'a [Hash]),
prev_roots: BTreeMap<Number, Hash>,
}
impl<'a, H, Number, Hash> ChangesTrieRootsStorage<H> for RootsStorage<'a, Number, Hash>
impl<'a, H, Number, Hash> ChangesTrieRootsStorage<H, Number> for RootsStorage<'a, Number, Hash>
where
H: Hasher,
Number: Send + Sync + Eq + ::std::cmp::Ord + Copy + UniqueSaturatedInto<u64>
+ UniqueSaturatedFrom<u64>,
Number: ::std::fmt::Display + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static,
Hash: 'a + Send + Sync + Clone + AsRef<[u8]>,
{
fn root(&self, _anchor: &ChangesTrieAnchorBlockId<H::Out>, block: u64) -> Result<Option<H::Out>, String> {
fn build_anchor(
&self,
_hash: H::Out,
) -> Result<state_machine::ChangesTrieAnchorBlockId<H::Out, Number>, String> {
Err("build_anchor is only called when building block".into())
}
fn root(
&self,
_anchor: &ChangesTrieAnchorBlockId<H::Out, Number>,
block: Number,
) -> Result<Option<H::Out>, String> {
// we can't ask for roots from parallel forks here => ignore anchor
let root = if block < self.roots.0.saturated_into::<u64>() {
let root = if block < self.roots.0 {
self.prev_roots.get(&Number::unique_saturated_from(block)).cloned()
} else {
block.checked_sub(self.roots.0.saturated_into::<u64>())
.and_then(|index| self.roots.1.get(index as usize))
.cloned()
let index: Option<usize> = block.checked_sub(&self.roots.0).and_then(|index| index.checked_into());
match index {
Some(index) => self.roots.1.get(index as usize).cloned(),
None => None,
}
};
Ok(root.map(|root| {