* Start to remove the `As` bound on `SimpleArtithmetic`

This just introduces standard numeric bounds, assuming a minimum of
`u32`. Also included is a saturating from/into trait allowing ergonomic
infallible conversion when you don't care if it saturates.

* Remove As from Balances trait

* Remove As from Aura module

* Remove As from Babe module

* Expunge `As` from contract

* Council module

* Democracy

* Finality tracker

* Grandpa

* First bit of indices

* indices

* Line lengths

* session

* system

* Staking

* Square up all other uses of As.

* RHD update

* Fix build/test

* Remove As trait

* line widths

* Remove final As ref

* Update srml/staking/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update core/client/src/cht.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update core/client/db/src/light.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* whitespace

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>
Co-Authored-By: André Silva <andre.beat@gmail.com>

* Bring back u32 check for number on CLI
This commit is contained in:
Gavin Wood
2019-05-22 23:11:38 +01:00
committed by GitHub
parent 36987c0205
commit 3860d7c810
60 changed files with 695 additions and 491 deletions
+7 -5
View File
@@ -44,7 +44,9 @@ use std::collections::BTreeSet;
use log::warn;
use client::error::{Error as ClientError, Result as ClientResult};
use runtime_primitives::traits::{Block as BlockT, NumberFor, As, Zero};
use runtime_primitives::traits::{
Block as BlockT, NumberFor, Zero, Bounded, SaturatedConversion, CheckedSub
};
use crate::cache::{CacheItemT, ComplexBlockId, EntryType};
use crate::cache::list_entry::{Entry, StorageEntry};
@@ -135,7 +137,7 @@ impl<Block: BlockT, T: CacheItemT, S: Storage<Block, T>> ListCache<Block, T, S>
// BUT since we're not guaranteeing to provide correct values for forks
// behind the finalized block, check if the block is finalized first
if !chain::is_finalized_block(&self.storage, at, As::sa(::std::u64::MAX))? {
if !chain::is_finalized_block(&self.storage, at, Bounded::max_value())? {
return Ok(None);
}
@@ -349,9 +351,9 @@ impl<Block: BlockT, T: CacheItemT, S: Storage<Block, T>> ListCache<Block, T, S>
) {
let mut do_pruning = || -> ClientResult<()> {
// calculate last ancient block number
let ancient_block = match block.number.as_().checked_sub(self.prune_depth.as_()) {
Some(number) => match self.storage.read_id(As::sa(number))? {
Some(hash) => ComplexBlockId::new(hash, As::sa(number)),
let ancient_block = match block.number.checked_sub(&self.prune_depth) {
Some(number) => match self.storage.read_id(number)? {
Some(hash) => ComplexBlockId::new(hash, number),
None => return Ok(()),
},
None => return Ok(()),
+3 -3
View File
@@ -25,7 +25,7 @@ use client::blockchain::Cache as BlockchainCache;
use client::error::Result as ClientResult;
use parity_codec::{Encode, Decode};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As, Zero};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero};
use consensus_common::well_known_cache_keys::Id as CacheKeyId;
use crate::utils::{self, COLUMN_META, db_err};
@@ -36,7 +36,7 @@ mod list_entry;
mod list_storage;
/// Minimal post-finalization age age of finalized blocks before they'll pruned.
const PRUNE_DEPTH: u64 = 1024;
const PRUNE_DEPTH: u32 = 1024;
/// The type of entry that is inserted to the cache.
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -166,7 +166,7 @@ fn get_cache_helper<'a, Block: BlockT>(
cache,
},
),
As::sa(PRUNE_DEPTH),
PRUNE_DEPTH.into(),
best_finalized_block.clone(),
)
})
+20 -17
View File
@@ -46,7 +46,10 @@ use parking_lot::{Mutex, RwLock};
use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash};
use primitives::storage::well_known_keys;
use runtime_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero, Digest, DigestItem};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, NumberFor, Zero, One, Digest, DigestItem,
SaturatedConversion, UniqueSaturatedFrom, UniqueSaturatedInto
};
use runtime_primitives::BuildStorage;
use state_machine::backend::Backend as StateBackend;
use executor::RuntimeInfo;
@@ -446,7 +449,7 @@ impl<Block: BlockT> DbChangesTrieStorage<Block> {
min_blocks_to_keep,
&state_machine::ChangesTrieAnchorBlockId {
hash: convert_hash(&block_hash),
number: block_num.as_(),
number: block_num.saturated_into::<u64>(),
},
|node| tx.delete(columns::CHANGES_TRIE, node.as_ref()));
}
@@ -477,19 +480,19 @@ impl<Block: BlockT> state_machine::ChangesTrieRootsStorage<Blake2Hasher> for DbC
}
// we need to get hash of the block to resolve changes trie root
let block_id = if block <= self.meta.read().finalized_number.as_() {
let block_id = if block <= self.meta.read().finalized_number.saturated_into::<u64>() {
// if block is finalized, we could just read canonical hash
BlockId::Number(As::sa(block))
BlockId::Number(block.saturated_into())
} else {
// the block is not finalized
let mut current_num = anchor.number;
let mut current_hash: Block::Hash = convert_hash(&anchor.hash);
let maybe_anchor_header: Block::Header = utils::require_header::<Block>(
&*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Number(As::sa(current_num))
&*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Number(current_num.saturated_into())
).map_err(|e| e.to_string())?;
if maybe_anchor_header.hash() == current_hash {
// if anchor is canonicalized, then the block is also canonicalized
BlockId::Number(As::sa(block))
BlockId::Number(block.saturated_into())
} else {
// else (block is not finalized + anchor is not canonicalized):
// => we should find the required block hash by traversing
@@ -770,7 +773,7 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
)
-> Result<(), client::error::Error>
{
let number_u64 = number.as_();
let number_u64 = number.saturated_into::<u64>();
if number_u64 > self.canonicalization_delay {
let new_canonical = number_u64 - self.canonicalization_delay;
@@ -781,7 +784,7 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
let hash = if new_canonical == number_u64 {
hash
} else {
::client::blockchain::HeaderBackend::hash(&self.blockchain, As::sa(new_canonical))?
::client::blockchain::HeaderBackend::hash(&self.blockchain, new_canonical.saturated_into())?
.expect("existence of block with number `new_canonical` \
implies existence of blocks with all numbers before it; qed")
};
@@ -865,7 +868,7 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
changeset.deleted.push(key);
}
}
let number_u64 = number.as_();
let number_u64 = number.saturated_into::<u64>();
let commit = self.storage.state_db.insert_block(&hash, number_u64, &pending_block.header.parent_hash(), changeset)
.map_err(|e: state_db::Error<io::Error>| client::error::Error::from(format!("State database error: {:?}", e)))?;
apply_state_commit(&mut transaction, commit);
@@ -978,7 +981,7 @@ impl<Block: BlockT<Hash=H256>> Backend<Block> {
{
let f_num = f_header.number().clone();
if self.storage.state_db.best_canonical().map(|c| f_num.as_() > c).unwrap_or(true) {
if self.storage.state_db.best_canonical().map(|c| f_num.saturated_into::<u64>() > c).unwrap_or(true) {
let parent_hash = f_header.parent_hash().clone();
let lookup_key = utils::number_and_hash_to_lookup_key(f_num, f_hash.clone());
@@ -1126,9 +1129,9 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
let revertible = best - finalized;
let n = if revertible < n { revertible } else { n };
for c in 0 .. n.as_() {
if best == As::sa(0) {
return Ok(As::sa(c))
for c in 0 .. n.saturated_into::<u64>() {
if best.is_zero() {
return Ok(c.saturated_into::<NumberFor<Block>>())
}
let mut transaction = DBTransaction::new();
match self.storage.state_db.revert_one() {
@@ -1138,7 +1141,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|| client::error::Error::UnknownBlock(
format!("Error reverting to {}. Block hash not found.", best)))?;
best -= As::sa(1); // prev block
best -= One::one(); // prev block
let hash = self.blockchain.hash(best)?.ok_or_else(
|| client::error::Error::UnknownBlock(
format!("Error reverting to {}. Block hash not found.", best)))?;
@@ -1150,7 +1153,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
self.blockchain.update_meta(hash, best, true, false);
self.blockchain.leaves.write().revert(removed.hash().clone(), removed.number().clone(), removed.parent_hash().clone());
}
None => return Ok(As::sa(c))
None => return Ok(c.saturated_into::<NumberFor<Block>>())
}
}
Ok(n)
@@ -1182,7 +1185,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
match self.blockchain.header(block) {
Ok(Some(ref hdr)) => {
let hash = hdr.hash();
if !self.storage.state_db.is_pruned(&hash, hdr.number().as_()) {
if !self.storage.state_db.is_pruned(&hash, (*hdr.number()).saturated_into::<u64>()) {
let root = H256::from_slice(hdr.state_root().as_ref());
let state = DbState::new(self.storage.clone(), root);
Ok(CachingState::new(state, self.shared_cache.clone(), Some(hash)))
@@ -1196,7 +1199,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
}
fn have_state_at(&self, hash: &Block::Hash, number: NumberFor<Block>) -> bool {
!self.storage.state_db.is_pruned(hash, number.as_())
!self.storage.state_db.is_pruned(hash, number.saturated_into::<u64>())
}
fn destroy_state(&self, mut state: Self::State) -> Result<(), client::error::Error> {
+8 -6
View File
@@ -17,6 +17,7 @@
//! RocksDB-based light client blockchain storage.
use std::{sync::Arc, collections::HashMap};
use std::convert::TryInto;
use parking_lot::RwLock;
use kvdb::{KeyValueDB, DBTransaction};
@@ -32,7 +33,8 @@ use parity_codec::{Decode, Encode};
use primitives::Blake2Hasher;
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT,
Zero, One, As, NumberFor, Digest, DigestItem};
Zero, One, SaturatedConversion, NumberFor, Digest, DigestItem
};
use consensus_common::well_known_cache_keys;
use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType};
use crate::utils::{self, meta_keys, Meta, db_err, open_database,
@@ -271,8 +273,8 @@ impl<Block: BlockT> LightStorage<Block> {
let new_cht_start: NumberFor<Block> = cht::start_number(cht::SIZE, new_cht_number);
let new_header_cht_root = cht::compute_root::<Block::Header, Blake2Hasher, _>(
cht::SIZE, new_cht_number, (new_cht_start.as_()..)
.map(|num| self.hash(As::sa(num)))
cht::SIZE, new_cht_number, (new_cht_start.saturated_into::<u64>()..)
.map(|num| self.hash(num.saturated_into()))
)?;
transaction.put(
columns::CHT,
@@ -283,8 +285,8 @@ impl<Block: BlockT> LightStorage<Block> {
// if the header includes changes trie root, let's build a changes tries roots CHT
if header.digest().log(DigestItem::as_changes_trie_root).is_some() {
let new_changes_trie_cht_root = cht::compute_root::<Block::Header, Blake2Hasher, _>(
cht::SIZE, new_cht_number, (new_cht_start.as_()..)
.map(|num| self.changes_trie_root(BlockId::Number(As::sa(num))))
cht::SIZE, new_cht_number, (new_cht_start.saturated_into::<u64>()..)
.map(|num| self.changes_trie_root(BlockId::Number(num.saturated_into())))
)?;
transaction.put(
columns::CHT,
@@ -530,7 +532,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
}
/// Build the key for inserting header-CHT at given block.
fn cht_key<N: As<u64>>(cht_type: u8, block: N) -> [u8; 5] {
fn cht_key<N: TryInto<u32>>(cht_type: u8, block: N) -> [u8; 5] {
let mut key = [cht_type; 5];
key[1..].copy_from_slice(&utils::number_index_key(block));
key
+20 -16
View File
@@ -19,6 +19,7 @@
use std::sync::Arc;
use std::io;
use std::convert::TryInto;
use kvdb::{KeyValueDB, DBTransaction};
use kvdb_rocksdb::{Database, DatabaseConfig};
@@ -28,7 +29,10 @@ use client;
use parity_codec::Decode;
use trie::DBValue;
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, Zero};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, Zero, UniqueSaturatedFrom,
UniqueSaturatedInto, SaturatedConversion, CheckedConversion
};
use crate::DatabaseSettings;
/// Number of columns in the db. Must be the same for both full && light dbs.
@@ -78,10 +82,8 @@ pub type NumberIndexKey = [u8; 4];
///
/// In the current database schema, this kind of key is only used for
/// lookups into an index, NOT for storing header data or others.
pub fn number_index_key<N>(n: N) -> NumberIndexKey where N: As<u64> {
let n: u64 = n.as_();
assert!(n & 0xffffffff00000000 == 0);
pub fn number_index_key<N: TryInto<u32>>(n: N) -> NumberIndexKey {
let n = n.checked_into::<u32>().unwrap();
[
(n >> 24) as u8,
((n >> 16) & 0xff) as u8,
@@ -93,7 +95,7 @@ pub fn number_index_key<N>(n: N) -> NumberIndexKey where N: As<u64> {
/// Convert number and hash into long lookup key for blocks that are
/// not in the canonical chain.
pub fn number_and_hash_to_lookup_key<N, H>(number: N, hash: H) -> Vec<u8> where
N: As<u64>,
N: TryInto<u32>,
H: AsRef<[u8]>
{
let mut lookup_key = number_index_key(number).to_vec();
@@ -103,18 +105,20 @@ pub fn number_and_hash_to_lookup_key<N, H>(number: N, hash: H) -> Vec<u8> where
/// Convert block lookup key into block number.
/// all block lookup keys start with the block number.
pub fn lookup_key_to_number<N>(key: &[u8]) -> client::error::Result<N> where N: As<u64> {
pub fn lookup_key_to_number<N>(key: &[u8]) -> client::error::Result<N> where
N: From<u32>
{
if key.len() < 4 {
return Err(client::error::Error::Backend("Invalid block key".into()));
}
Ok((key[0] as u64) << 24
| (key[1] as u64) << 16
| (key[2] as u64) << 8
| (key[3] as u64)).map(As::sa)
Ok((key[0] as u32) << 24
| (key[1] as u32) << 16
| (key[2] as u32) << 8
| (key[3] as u32)).map(Into::into)
}
/// Delete number to hash mapping in DB transaction.
pub fn remove_number_to_key_mapping<N: As<u64>>(
pub fn remove_number_to_key_mapping<N: TryInto<u32>>(
transaction: &mut DBTransaction,
key_lookup_col: Option<u32>,
number: N,
@@ -123,7 +127,7 @@ pub fn remove_number_to_key_mapping<N: As<u64>>(
}
/// Remove key mappings.
pub fn remove_key_mappings<N: As<u64>, H: AsRef<[u8]>>(
pub fn remove_key_mappings<N: TryInto<u32>, H: AsRef<[u8]>>(
transaction: &mut DBTransaction,
key_lookup_col: Option<u32>,
number: N,
@@ -135,7 +139,7 @@ pub fn remove_key_mappings<N: As<u64>, H: AsRef<[u8]>>(
/// Place a number mapping into the database. This maps number to current perceived
/// block hash at that position.
pub fn insert_number_to_key_mapping<N: As<u64> + Clone, H: AsRef<[u8]>>(
pub fn insert_number_to_key_mapping<N: TryInto<u32> + Clone, H: AsRef<[u8]>>(
transaction: &mut DBTransaction,
key_lookup_col: Option<u32>,
number: N,
@@ -149,7 +153,7 @@ pub fn insert_number_to_key_mapping<N: As<u64> + Clone, H: AsRef<[u8]>>(
}
/// Insert a hash to key mapping in the database.
pub fn insert_hash_to_key_mapping<N: As<u64>, H: AsRef<[u8]> + Clone>(
pub fn insert_hash_to_key_mapping<N: TryInto<u32>, H: AsRef<[u8]> + Clone>(
transaction: &mut DBTransaction,
key_lookup_col: Option<u32>,
number: N,
@@ -171,7 +175,7 @@ pub fn block_id_to_lookup_key<Block>(
id: BlockId<Block>
) -> Result<Option<Vec<u8>>, client::error::Error> where
Block: BlockT,
::runtime_primitives::traits::NumberFor<Block>: As<u64>,
::runtime_primitives::traits::NumberFor<Block>: UniqueSaturatedFrom<u64> + UniqueSaturatedInto<u64>,
{
let res = match id {
BlockId::Number(n) => db.get(