* 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
+1
View File
@@ -4119,6 +4119,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"sr-version 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
+3 -3
View File
@@ -29,7 +29,7 @@ use substrate_telemetry::{telemetry, SUBSTRATE_INFO};
use log::{info, warn};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Header, As};
use runtime_primitives::traits::{Header, SaturatedConversion};
/// Spawn informant on the event loop
pub fn start<C>(service: &Service<C>, exit: ::exit_future::Exit, handle: TaskExecutor) where
@@ -47,7 +47,7 @@ pub fn start<C>(service: &Service<C>, exit: ::exit_future::Exit, handle: TaskExe
let display_notifications = network.status().for_each(move |sync_status| {
if let Ok(info) = client.info() {
let best_number: u64 = info.chain.best_number.as_();
let best_number = info.chain.best_number.saturated_into::<u64>();
let best_hash = info.chain.best_hash;
let num_peers = sync_status.num_peers;
let speed = move || speed(best_number, last_number, last_update);
@@ -59,7 +59,7 @@ pub fn start<C>(service: &Service<C>, exit: ::exit_future::Exit, handle: TaskExe
};
last_number = Some(best_number);
let txpool_status = txpool.status();
let finalized_number: u64 = info.chain.finalized_number.as_();
let finalized_number: u64 = info.chain.finalized_number.saturated_into::<u64>();
let bandwidth_download = network.average_download_per_sec();
let bandwidth_upload = network.average_upload_per_sec();
info!(
+2 -3
View File
@@ -26,7 +26,6 @@ pub mod error;
pub mod informant;
use client::ExecutionStrategies;
use runtime_primitives::traits::As;
use service::{
ServiceFactory, FactoryFullConfiguration, RuntimeGenesis,
FactoryGenesis, PruningMode, ChainSpec,
@@ -627,7 +626,7 @@ where
};
service::chain_ops::export_blocks::<F, _, _>(
config, exit.into_exit(), file, As::sa(from), to.map(As::sa), json
config, exit.into_exit(), file, from.into(), to.map(Into::into), json
).map_err(Into::into)
}
@@ -663,7 +662,7 @@ where
{
let config = create_config_with_db_path::<F, _>(spec_factory, &cli.shared_params, version)?;
let blocks = cli.num;
Ok(service::chain_ops::revert_chain::<F>(config, As::sa(blocks))?)
Ok(service::chain_ops::revert_chain::<F>(config, blocks.into())?)
}
fn purge_chain<F, S>(
+3 -3
View File
@@ -533,11 +533,11 @@ pub struct ExportBlocksCmd {
/// Specify starting block number. 1 by default.
#[structopt(long = "from", value_name = "BLOCK")]
pub from: Option<u64>,
pub from: Option<u32>,
/// Specify last block number. Best block by default.
#[structopt(long = "to", value_name = "BLOCK")]
pub to: Option<u64>,
pub to: Option<u32>,
/// Use JSON output rather than binary.
#[structopt(long = "json")]
@@ -573,7 +573,7 @@ impl_get_log_filter!(ImportBlocksCmd);
pub struct RevertCmd {
/// Number of blocks to revert.
#[structopt(default_value = "256")]
pub num: u64,
pub num: u32,
#[allow(missing_docs)]
#[structopt(flatten)]
+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(
+23 -11
View File
@@ -29,7 +29,12 @@ use hash_db;
use trie;
use primitives::{H256, convert_hash};
use runtime_primitives::traits::{As, Header as HeaderT, SimpleArithmetic, One};
// We're using saturatedconversion in order to go back and forth to `u64`. this is stupid.
// instead we should just make the CHT generic over the block number.
use runtime_primitives::traits::{
Header as HeaderT, SimpleArithmetic, One, SaturatedConversion,
UniqueSaturatedInto
};
use state_machine::backend::InMemory as InMemoryState;
use state_machine::{MemoryDB, TrieBackend, Backend as StateBackend,
prove_read_on_trie_backend, read_proof_check, read_proof_check_on_proving_backend};
@@ -183,7 +188,7 @@ pub fn for_each_cht_group<Header, I, F, P>(
let mut current_cht_num = None;
let mut current_cht_blocks = Vec::new();
for block in blocks {
let new_cht_num = match block_to_cht_number(cht_size, block.as_()) {
let new_cht_num = match block_to_cht_number(cht_size, block.saturated_into()) {
Some(new_cht_num) => new_cht_num,
None => return Err(ClientError::Backend(format!(
"Cannot compute CHT root for the block #{}", block)).into()
@@ -198,7 +203,7 @@ pub fn for_each_cht_group<Header, I, F, P>(
functor_param = functor(
functor_param,
As::sa(current_cht_num),
current_cht_num.saturated_into(),
::std::mem::replace(&mut current_cht_blocks, Vec::new()),
)?;
}
@@ -210,7 +215,7 @@ pub fn for_each_cht_group<Header, I, F, P>(
if let Some(current_cht_num) = current_cht_num {
functor(
functor_param,
As::sa(current_cht_num),
current_cht_num.saturated_into(),
::std::mem::replace(&mut current_cht_blocks, Vec::new()),
)?;
}
@@ -233,7 +238,10 @@ fn build_pairs<Header, I>(
let mut hash_number = start_num;
for hash in hashes.into_iter().take(cht_size as usize) {
let hash = hash?.ok_or_else(|| ClientError::from(
ClientError::MissingHashRequiredForCHT(cht_num.as_(), hash_number.as_())
ClientError::MissingHashRequiredForCHT(
cht_num.saturated_into::<u64>(),
hash_number.saturated_into::<u64>()
)
))?;
pairs.push((
encode_cht_key(hash_number).to_vec(),
@@ -245,7 +253,10 @@ fn build_pairs<Header, I>(
if pairs.len() as u64 == cht_size {
Ok(pairs)
} else {
Err(ClientError::MissingHashRequiredForCHT(cht_num.as_(), hash_number.as_()))
Err(ClientError::MissingHashRequiredForCHT(
cht_num.saturated_into::<u64>(),
hash_number.saturated_into::<u64>()
))
}
}
@@ -256,12 +267,12 @@ fn build_pairs<Header, I>(
/// This is because the genesis hash is assumed to be known
/// and including it would be redundant.
pub fn start_number<N: SimpleArithmetic>(cht_size: u64, cht_num: N) -> N {
(cht_num * As::sa(cht_size)) + N::one()
(cht_num * cht_size.saturated_into()) + N::one()
}
/// Get the ending block of a given CHT.
pub fn end_number<N: SimpleArithmetic>(cht_size: u64, cht_num: N) -> N {
(cht_num + N::one()) * As::sa(cht_size)
(cht_num + N::one()) * cht_size.saturated_into()
}
/// Convert a block number to a CHT number.
@@ -270,13 +281,14 @@ pub fn block_to_cht_number<N: SimpleArithmetic>(cht_size: u64, block_num: N) ->
if block_num == N::zero() {
None
} else {
Some((block_num - N::one()) / As::sa(cht_size))
Some((block_num - N::one()) / cht_size.saturated_into())
}
}
/// Convert header number into CHT key.
pub fn encode_cht_key<N: As<u64>>(number: N) -> Vec<u8> {
let number: u64 = number.as_();
pub fn encode_cht_key<N: UniqueSaturatedInto<u64>>(number: N) -> Vec<u8> {
// why not just use Encode?
let number: u64 = number.saturated_into();
vec![
(number >> 56) as u8,
((number >> 48) & 0xff) as u8,
+63 -33
View File
@@ -35,8 +35,9 @@ use consensus::{
SelectChain, self,
};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight,
BlockNumberToHash, ApiRef, ProvideRuntimeApi, Digest, DigestItem
Block as BlockT, Header as HeaderT, Zero, NumberFor, CurrentHeight,
BlockNumberToHash, ApiRef, ProvideRuntimeApi, Digest, DigestItem,
SaturatedConversion, One
};
use runtime_primitives::BuildStorage;
use crate::runtime_api::{
@@ -82,7 +83,11 @@ pub type ImportNotifications<Block> = mpsc::UnboundedReceiver<BlockImportNotific
/// A stream of block finality notifications.
pub type FinalityNotifications<Block> = mpsc::UnboundedReceiver<FinalityNotification<Block>>;
type StorageUpdate<B, Block> = <<<B as backend::Backend<Block, Blake2Hasher>>::BlockImportOperation as BlockImportOperation<Block, Blake2Hasher>>::State as state_machine::Backend<Blake2Hasher>>::Transaction;
type StorageUpdate<B, Block> = <
<
<B as backend::Backend<Block, Blake2Hasher>>::BlockImportOperation
as BlockImportOperation<Block, Blake2Hasher>
>::State as state_machine::Backend<Blake2Hasher>>::Transaction;
type ChangesUpdate = trie::MemoryDB<Blake2Hasher>;
/// Execution strategies settings.
@@ -146,13 +151,17 @@ pub trait BlockchainEvents<Block: BlockT> {
/// Get storage changes event stream.
///
/// Passing `None` as `filter_keys` subscribes to all storage changes.
fn storage_changes_notification_stream(&self, filter_keys: Option<&[StorageKey]>) -> error::Result<StorageEventStream<Block::Hash>>;
fn storage_changes_notification_stream(&self,
filter_keys: Option<&[StorageKey]>
) -> error::Result<StorageEventStream<Block::Hash>>;
}
/// Fetch block body by ID.
pub trait BlockBody<Block: BlockT> {
/// Get block body by ID. Returns `None` if the body is not stored.
fn block_body(&self, id: &BlockId<Block>) -> error::Result<Option<Vec<<Block as BlockT>::Extrinsic>>>;
fn block_body(&self,
id: &BlockId<Block>
) -> error::Result<Option<Vec<<Block as BlockT>::Extrinsic>>>;
}
/// Client info
@@ -242,11 +251,15 @@ impl<H> PrePostHeader<H> {
pub fn new_in_mem<E, Block, S, RA>(
executor: E,
genesis_storage: S,
) -> error::Result<Client<in_mem::Backend<Block, Blake2Hasher>, LocalCallExecutor<in_mem::Backend<Block, Blake2Hasher>, E>, Block, RA>>
where
E: CodeExecutor<Blake2Hasher> + RuntimeInfo,
S: BuildStorage,
Block: BlockT<Hash=H256>,
) -> error::Result<Client<
in_mem::Backend<Block, Blake2Hasher>,
LocalCallExecutor<in_mem::Backend<Block, Blake2Hasher>, E>,
Block,
RA
>> where
E: CodeExecutor<Blake2Hasher> + RuntimeInfo,
S: BuildStorage,
Block: BlockT<Hash=H256>,
{
new_with_backend(Arc::new(in_mem::Backend::new()), executor, genesis_storage)
}
@@ -286,7 +299,10 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
backend.begin_state_operation(&mut op, BlockId::Hash(Default::default()))?;
let state_root = op.reset_storage(genesis_storage, children_genesis_storage)?;
let genesis_block = genesis::construct_genesis_block::<Block>(state_root.into());
info!("Initializing Genesis block/state (state: {}, header-hash: {})", genesis_block.header().state_root(), genesis_block.header().hash());
info!("Initializing Genesis block/state (state: {}, header-hash: {})",
genesis_block.header().state_root(),
genesis_block.header().hash()
);
op.set_block_data(
genesis_block.deconstruct().0,
Some(vec![]),
@@ -380,7 +396,8 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
/// Get the code at a given block.
pub fn code_at(&self, id: &BlockId<Block>) -> error::Result<Vec<u8>> {
Ok(self.storage(id, &StorageKey(well_known_keys::CODE.to_vec()))?
.expect("None is returned if there's no value stored for the given key; ':code' key is always defined; qed").0)
.expect("None is returned if there's no value stored for the given key;\
':code' key is always defined; qed").0)
}
/// Get the RuntimeVersion at a given block.
@@ -419,7 +436,11 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
/// AND returning execution proof.
///
/// No changes are made.
pub fn execution_proof(&self, id: &BlockId<Block>, method: &str, call_data: &[u8]) -> error::Result<(Vec<u8>, Vec<Vec<u8>>)> {
pub fn execution_proof(&self,
id: &BlockId<Block>,
method: &str,
call_data: &[u8]
) -> error::Result<(Vec<u8>, Vec<Vec<u8>>)> {
let state = self.state_at(id)?;
let header = self.prepare_environment_block(id)?;
prove_execution(state, header, &self.executor, method, call_data)
@@ -431,18 +452,23 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
}
/// Get block hash by number.
pub fn block_hash(&self, block_number: <<Block as BlockT>::Header as HeaderT>::Number) -> error::Result<Option<Block::Hash>> {
pub fn block_hash(&self,
block_number: <<Block as BlockT>::Header as HeaderT>::Number
) -> error::Result<Option<Block::Hash>> {
self.backend.blockchain().hash(block_number)
}
/// Reads given header and generates CHT-based header proof for CHT of given size.
pub fn header_proof_with_cht_size(&self, id: &BlockId<Block>, cht_size: u64) -> error::Result<(Block::Header, Vec<Vec<u8>>)> {
pub fn header_proof_with_cht_size(&self,
id: &BlockId<Block>,
cht_size: u64
) -> error::Result<(Block::Header, Vec<Vec<u8>>)> {
let proof_error = || error::Error::Backend(format!("Failed to generate header proof for {:?}", id));
let header = self.backend.blockchain().expect_header(*id)?;
let block_num = *header.number();
let cht_num = cht::block_to_cht_number(cht_size, block_num).ok_or_else(proof_error)?;
let cht_start = cht::start_number(cht_size, cht_num);
let headers = (cht_start.as_()..).map(|num| self.block_hash(As::sa(num)));
let headers = (cht_start.saturated_into()..).map(|num| self.block_hash(num.saturated_into()));
let proof = cht::build_proof::<Block::Header, Blake2Hasher, _, _>(cht_size, cht_num, ::std::iter::once(block_num), headers)?;
Ok((header, proof))
}
@@ -460,14 +486,14 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
Some((config, storage)) => (config, storage),
None => return Ok(None),
};
let first = first.as_();
let last_num = self.backend.blockchain().expect_block_number_from_id(&last)?.as_();
let first = first.saturated_into::<u64>();
let last_num = self.backend.blockchain().expect_block_number_from_id(&last)?.saturated_into::<u64>();
if first > last_num {
return Err(error::Error::ChangesTrieAccessFailed("Invalid changes trie range".into()));
}
let finalized_number = self.backend.blockchain().info()?.finalized_number;
let oldest = storage.oldest_changes_trie_block(&config, finalized_number.as_());
let first = As::sa(::std::cmp::max(first, oldest));
let oldest = storage.oldest_changes_trie_block(&config, finalized_number.saturated_into::<u64>());
let first = ::std::cmp::max(first, oldest).saturated_into::<NumberFor<Block>>();
Ok(Some((first, last)))
}
@@ -480,20 +506,20 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
key: &StorageKey
) -> error::Result<Vec<(NumberFor<Block>, u32)>> {
let (config, storage) = self.require_changes_trie()?;
let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?.as_();
let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?.saturated_into::<u64>();
let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?;
key_changes::<_, Blake2Hasher>(
&config,
&*storage,
first.as_(),
first.saturated_into::<u64>(),
&ChangesTrieAnchorBlockId {
hash: convert_hash(&last_hash),
number: last_number,
},
self.backend.blockchain().info()?.best_number.as_(),
self.backend.blockchain().info()?.best_number.saturated_into::<u64>(),
&key.0)
.and_then(|r| r.map(|r| r.map(|(block, tx)| (As::sa(block), tx))).collect::<Result<_, _>>())
.and_then(|r| r.map(|r| r.map(|(block, tx)| (block.saturated_into(), tx))).collect::<Result<_, _>>())
.map_err(|err| error::Error::ChangesTrieAccessFailed(err))
}
@@ -543,7 +569,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
if block < self.min {
if let Some(ref root) = root {
self.required_roots_proofs.lock().insert(
As::sa(block),
block.saturated_into(),
root.clone()
);
}
@@ -563,7 +589,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
let recording_storage = AccessedRootsRecorder::<Block> {
storage,
min: min_number.as_(),
min: min_number.saturated_into::<u64>(),
required_roots_proofs: Mutex::new(BTreeMap::new()),
};
@@ -573,8 +599,12 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
);
// fetch key changes proof
let first_number = self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(first))?.as_();
let last_number = self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(last))?.as_();
let first_number = self.backend.blockchain()
.expect_block_number_from_id(&BlockId::Hash(first))?
.saturated_into::<u64>();
let last_number = self.backend.blockchain()
.expect_block_number_from_id(&BlockId::Hash(last))?
.saturated_into::<u64>();
let key_changes_proof = key_changes_proof::<_, Blake2Hasher>(
&config,
&recording_storage,
@@ -583,7 +613,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
hash: convert_hash(&last),
number: last_number,
},
max_number.as_(),
max_number.saturated_into::<u64>(),
&key.0
)
.map_err(|err| error::Error::from(error::Error::ChangesTrieAccessFailed(err)))?;
@@ -628,7 +658,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
blocks: Vec<NumberFor<Block>>
) -> error::Result<Vec<Vec<u8>>> {
let cht_start = cht::start_number(cht_size, cht_num);
let roots = (cht_start.as_()..).map(|num| self.header(&BlockId::Number(As::sa(num)))
let roots = (cht_start.saturated_into()..).map(|num| self.header(&BlockId::Number(num.saturated_into()))
.map(|block| block.and_then(|block| block.digest().log(DigestItem::as_changes_trie_root).cloned())));
let proof = cht::build_proof::<Block::Header, Blake2Hasher, _, _>(cht_size, cht_num, blocks, roots)?;
Ok(proof)
@@ -777,7 +807,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
};
let hash = import_headers.post().hash();
let height: u64 = import_headers.post().number().as_();
let height = (*import_headers.post().number()).saturated_into::<u64>();
*self.importing_block.write() = Some(hash);
@@ -1201,7 +1231,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
let mut ancestor = load_header(ancestor_hash)?;
let mut uncles = Vec::new();
for _generation in 0..max_generation.as_() {
for _generation in 0..max_generation.saturated_into() {
let children = self.backend.blockchain().children(ancestor_hash)?;
uncles.extend(children.into_iter().filter(|h| h != &current_hash));
current_hash = ancestor_hash;
@@ -1224,7 +1254,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
/// Prepare in-memory header that is used in execution environment.
fn prepare_environment_block(&self, parent: &BlockId<Block>) -> error::Result<Block::Header> {
Ok(<<Block as BlockT>::Header as HeaderT>::new(
self.backend.blockchain().expect_block_number_from_id(parent)? + As::sa(1),
self.backend.blockchain().expect_block_number_from_id(parent)? + One::one(),
Default::default(),
Default::default(),
self.backend.blockchain().expect_block_hash_from_id(&parent)?,
+10 -4
View File
@@ -21,8 +21,10 @@ use std::sync::Arc;
use parking_lot::RwLock;
use primitives::{ChangesTrieConfiguration, storage::well_known_keys};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero,
NumberFor, As, Digest, DigestItem};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, Zero,
NumberFor, SaturatedConversion, Digest, DigestItem
};
use runtime_primitives::{Justification, StorageOverlay, ChildrenStorageOverlay};
use state_machine::backend::{Backend as StateBackend, InMemory};
use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId};
@@ -619,7 +621,11 @@ where
if let Some(changes_trie_root) = changes_trie_root {
if let Some(changes_trie_update) = operation.changes_trie_update {
let changes_trie_root: H::Out = changes_trie_root.into();
self.changes_trie_storage.0.insert(header.number().as_(), changes_trie_root, changes_trie_update);
self.changes_trie_storage.0.insert(
(*header.number()).saturated_into::<u64>(),
changes_trie_root,
changes_trie_update
);
}
}
@@ -668,7 +674,7 @@ where
}
fn revert(&self, _n: NumberFor<Block>) -> error::Result<NumberFor<Block>> {
Ok(As::sa(0))
Ok(Zero::zero())
}
}
@@ -26,7 +26,7 @@ use futures::{IntoFuture, Future};
use parity_codec::{Encode, Decode};
use primitives::{H256, Blake2Hasher, convert_hash, NativeOrEncoded, OffchainExt};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT};
use runtime_primitives::traits::{One, Block as BlockT, Header as HeaderT};
use state_machine::{
self, Backend as StateBackend, CodeExecutor, OverlayedChanges,
ExecutionStrategy, create_proof_check_backend,
@@ -444,7 +444,7 @@ pub fn check_execution_proof<Header, E, H>(
let mut changes = OverlayedChanges::default();
let trie_backend = create_proof_check_backend(root, remote_proof)?;
let next_block = <Header as HeaderT>::new(
*request.header.number() + As::sa(1),
*request.header.number() + One::one(),
Default::default(),
Default::default(),
request.header.hash(),
+16 -10
View File
@@ -24,7 +24,10 @@ use futures::IntoFuture;
use hash_db::{HashDB, Hasher};
use parity_codec::Encode;
use primitives::{ChangesTrieConfiguration, convert_hash};
use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor,
UniqueSaturatedInto, UniqueSaturatedFrom, SaturatedConversion
};
use state_machine::{CodeExecutor, ChangesTrieRootsStorage, ChangesTrieAnchorBlockId,
TrieBackend, read_proof_check, key_changes_proof_check,
create_proof_check_backend_storage, read_child_proof_check};
@@ -288,14 +291,16 @@ impl<E, H, B: BlockT, S: BlockchainStorage<B>, F> LightDataChecker<E, H, B, S, F
prev_roots: remote_roots,
},
remote_proof,
request.first_block.0.as_(),
request.first_block.0.saturated_into::<u64>(),
&ChangesTrieAnchorBlockId {
hash: convert_hash(&request.last_block.1),
number: request.last_block.0.as_(),
number: request.last_block.0.saturated_into::<u64>(),
},
remote_max_block.as_(),
remote_max_block.saturated_into::<u64>(),
&request.key)
.map(|pairs| pairs.into_iter().map(|(b, x)| (As::sa(b), x)).collect())
.map(|pairs| pairs.into_iter().map(|(b, x)|
(b.saturated_into::<NumberFor<B>>(), x)
).collect())
.map_err(|err| ClientError::ChangesTrieAccessFailed(err))
}
@@ -438,7 +443,7 @@ 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: As<u64>, Hash: 'a> {
struct RootsStorage<'a, Number: UniqueSaturatedInto<u64> + UniqueSaturatedFrom<u64>, Hash: 'a> {
roots: (Number, &'a [Hash]),
prev_roots: BTreeMap<Number, Hash>,
}
@@ -446,15 +451,16 @@ struct RootsStorage<'a, Number: As<u64>, Hash: 'a> {
impl<'a, H, Number, Hash> ChangesTrieRootsStorage<H> for RootsStorage<'a, Number, Hash>
where
H: Hasher,
Number: Send + Sync + Eq + ::std::cmp::Ord + Copy + As<u64>,
Number: Send + Sync + Eq + ::std::cmp::Ord + Copy + UniqueSaturatedInto<u64>
+ UniqueSaturatedFrom<u64>,
Hash: 'a + Send + Sync + Clone + AsRef<[u8]>,
{
fn root(&self, _anchor: &ChangesTrieAnchorBlockId<H::Out>, block: u64) -> Result<Option<H::Out>, String> {
// we can't ask for roots from parallel forks here => ignore anchor
let root = if block < self.roots.0.as_() {
self.prev_roots.get(&As::sa(block)).cloned()
let root = if block < self.roots.0.saturated_into::<u64>() {
self.prev_roots.get(&Number::unique_saturated_from(block)).cloned()
} else {
block.checked_sub(self.roots.0.as_())
block.checked_sub(self.roots.0.saturated_into::<u64>())
.and_then(|index| self.roots.1.get(index as usize))
.cloned()
};
@@ -13,6 +13,7 @@ primitives = { package = "substrate-primitives", path= "../../primitives" }
inherents = { package = "substrate-inherents", path = "../../inherents" }
error-chain = "0.12"
futures = "0.1"
rstd = { package = "sr-std", path = "../../sr-std" }
runtime_version = { package = "sr-version", path = "../../sr-version" }
runtime_primitives = { package = "sr-primitives", path = "../../sr-primitives" }
tokio-timer = "0.2"
@@ -19,11 +19,13 @@
use super::MAX_BLOCK_SIZE;
use parity_codec::Encode;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, One, CheckedConversion};
use error_chain::{error_chain, error_chain_processing, impl_error_chain_processed,
impl_extract_backtrace, impl_error_chain_kind, bail};
type BlockNumber = u64;
// This is just a best effort to encode the number. None indicated that it's too big to encode
// in a u128.
type BlockNumber = Option<u128>;
error_chain! {
errors {
@@ -37,7 +39,7 @@ error_chain! {
}
WrongNumber(expected: BlockNumber, got: BlockNumber) {
description("Proposal had wrong number."),
display("Proposal had wrong number. Expected {}, got {}", expected, got),
display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got),
}
ProposalTooLarge(size: usize) {
description("Proposal exceeded the maximum size."),
@@ -72,8 +74,11 @@ pub fn evaluate_initial<Block: BlockT>(
));
}
if parent_number.as_() + 1 != proposal.header().number().as_() {
bail!(ErrorKind::WrongNumber(parent_number.as_() + 1, proposal.header().number().as_()));
if parent_number + One::one() != *proposal.header().number() {
bail!(ErrorKind::WrongNumber(
parent_number.checked_into::<u128>().map(|x| x + 1),
(*proposal.header().number()).checked_into::<u128>()
));
}
Ok(())
+5 -2
View File
@@ -45,7 +45,10 @@ use client::{Client as SubstrateClient, CallExecutor};
use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, OldTxQueue, BlockBuilderError};
use runtime_primitives::generic::{BlockId, Era, ImportResult, ImportBlock, BlockOrigin};
use runtime_primitives::traits::{Block, Header};
use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, As, BlockNumberToHash};
use runtime_primitives::traits::{
Block as BlockT, Hash as HashT, Header as HeaderT,
BlockNumberToHash, SaturatedConversion
};
use runtime_primitives::Justification;
use primitives::{AuthorityId, ed25519, Blake2Hasher, ed25519::LocalizedSignature};
use srml_system::Trait as SystemT;
@@ -1246,7 +1249,7 @@ impl<C, A> LocalProposer<<C as AuthoringApi>::Block> for Proposer<C, A> where
for (target, misbehavior) in misbehavior {
let report = MisbehaviorReport {
parent_hash: self.parent_hash.into(),
parent_number: self.parent_number.as_(),
parent_number: self.parent_number.saturated_into::<u64>(),
target,
misbehavior: match misbehavior {
GenericMisbehavior::ProposeOutOfTurn(_, _, _) => continue,
@@ -34,7 +34,7 @@ use grandpa::{
};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{
As, Block as BlockT, Header as HeaderT, NumberFor, One, Zero, BlockNumberToHash,
Block as BlockT, Header as HeaderT, NumberFor, One, Zero, BlockNumberToHash,
};
use substrate_primitives::{Blake2Hasher, ed25519, H256, Pair};
use substrate_telemetry::{telemetry, CONSENSUS_INFO};
@@ -669,7 +669,7 @@ where
&*self.inner,
&self.authority_set,
&self.consensus_changes,
Some(As::sa(self.config.justification_period)),
Some(self.config.justification_period.into()),
hash,
number,
(round, commit).into(),
+1 -1
View File
@@ -157,7 +157,7 @@ pub struct Config {
/// Justification generation period (in blocks). GRANDPA will try to generate justifications
/// at least every justification_period blocks. There are some other events which might cause
/// justification generation.
pub justification_period: u64,
pub justification_period: u32,
/// The local signing key.
pub local_key: Option<Arc<ed25519::Pair>>,
/// Some local identifier of the voter.
+6 -6
View File
@@ -21,7 +21,7 @@ use std::collections::{HashMap, BTreeMap};
use std::collections::hash_map::Entry;
use log::trace;
use network_libp2p::PeerId;
use runtime_primitives::traits::{Block as BlockT, NumberFor, As};
use runtime_primitives::traits::{Block as BlockT, NumberFor, One};
use crate::message;
const MAX_PARALLEL_DOWNLOADS: u32 = 1;
@@ -48,7 +48,7 @@ impl<B: BlockT> BlockRangeState<B> {
pub fn len(&self) -> NumberFor<B> {
match *self {
BlockRangeState::Downloading { len, .. } => len,
BlockRangeState::Complete(ref blocks) => As::sa(blocks.len() as u64),
BlockRangeState::Complete(ref blocks) => (blocks.len() as u32).into(),
}
}
}
@@ -102,8 +102,8 @@ impl<B: BlockT> BlockCollection<B> {
/// Returns a set of block hashes that require a header download. The returned set is marked as being downloaded.
pub fn needed_blocks(&mut self, who: PeerId, count: usize, peer_best: NumberFor<B>, common: NumberFor<B>) -> Option<Range<NumberFor<B>>> {
// First block number that we need to download
let first_different = common + As::sa(1);
let count = As::sa(count as u64);
let first_different = common + <NumberFor<B>>::one();
let count = (count as u32).into();
let (mut range, downloading) = {
let mut downloading_iter = self.blocks.iter().peekable();
let mut prev: Option<(&NumberFor<B>, &BlockRangeState<B>)> = None;
@@ -132,7 +132,7 @@ impl<B: BlockT> BlockCollection<B> {
trace!(target: "sync", "Out of range for peer {} ({} vs {})", who, range.start, peer_best);
return None;
}
range.end = cmp::min(peer_best + As::sa(1), range.end);
range.end = cmp::min(peer_best + One::one(), range.end);
self.peer_requests.insert(who, range.start);
self.blocks.insert(range.start, BlockRangeState::Downloading { len: range.end - range.start, downloading: downloading + 1 });
if range.end <= range.start {
@@ -150,7 +150,7 @@ impl<B: BlockT> BlockCollection<B> {
for (start, range_data) in &mut self.blocks {
match range_data {
&mut BlockRangeState::Complete(ref mut blocks) if *start <= prev => {
prev = *start + As::sa(blocks.len() as u64);
prev = *start + (blocks.len() as u32).into();
let mut blocks = mem::replace(blocks, Vec::new());
drained.append(&mut blocks);
ranges.push(*start);
+9 -6
View File
@@ -19,7 +19,10 @@ use network_libp2p::PeerId;
use primitives::storage::StorageKey;
use consensus::{import_queue::IncomingBlock, import_queue::Origin, BlockOrigin};
use runtime_primitives::{generic::BlockId, ConsensusEngineId, Justification};
use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, NumberFor, Zero};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, NumberFor, One, Zero,
CheckedSub, SaturatedConversion
};
use consensus::import_queue::SharedFinalityProofRequestBuilder;
use crate::message::{
self, BlockRequest as BlockRequestMessage,
@@ -572,9 +575,9 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
};
blocks.push(block_data);
match request.direction {
message::Direction::Ascending => id = BlockId::Number(number + As::sa(1)),
message::Direction::Ascending => id = BlockId::Number(number + One::one()),
message::Direction::Descending => {
if number == As::sa(0) {
if number.is_zero() {
break;
}
id = BlockId::Hash(parent_hash)
@@ -716,9 +719,9 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
.and_then(|info| info.best_queued_number)
.unwrap_or_else(|| Zero::zero());
let blocks_difference = self_best_block
.as_()
.checked_sub(status.best_number.as_())
.unwrap_or(0);
.checked_sub(&status.best_number)
.unwrap_or_else(Zero::zero)
.saturated_into::<u64>();
if blocks_difference > LIGHT_MAXIMAL_BLOCKS_DIFFERENCE {
debug!(target: "sync", "Peer {} is far behind us and will unable to serve light requests", who);
network_out.report_peer(who.clone(), PEER_BEHIND_US_LIGHT_REPUTATION_CHANGE);
+37 -28
View File
@@ -40,7 +40,10 @@ use consensus::{BlockOrigin, import_queue::{IncomingBlock, SharedFinalityProofRe
use client::error::Error as ClientError;
use crate::blocks::BlockCollection;
use crate::sync::extra_requests::ExtraRequestsAggregator;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero, CheckedSub};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, NumberFor, Zero, One,
CheckedSub, SaturatedConversion
};
use runtime_primitives::{Justification, generic::BlockId};
use crate::message;
use crate::config::Roles;
@@ -204,7 +207,7 @@ impl<B: BlockT> ChainSync<B> {
fn state(&self, best_seen: &Option<NumberFor<B>>) -> SyncState {
match best_seen {
&Some(n) if n > self.best_queued_number && n - self.best_queued_number > As::sa(5) => SyncState::Downloading,
&Some(n) if n > self.best_queued_number && n - self.best_queued_number > 5.into() => SyncState::Downloading,
_ => SyncState::Idle,
}
}
@@ -251,7 +254,7 @@ impl<B: BlockT> ChainSync<B> {
protocol.report_peer(who.clone(), i32::min_value());
protocol.disconnect_peer(who);
},
(Ok(BlockStatus::Unknown), b) if b == As::sa(0) => {
(Ok(BlockStatus::Unknown), b) if b.is_zero() => {
info!("New peer with unknown genesis hash {} ({}).", info.best_hash, info.best_number);
protocol.report_peer(who.clone(), i32::min_value());
protocol.disconnect_peer(who);
@@ -269,28 +272,32 @@ impl<B: BlockT> ChainSync<B> {
}
(Ok(BlockStatus::Unknown), _) => {
let our_best = self.best_queued_number;
if our_best > As::sa(0) {
let common_best = ::std::cmp::min(our_best, info.best_number);
debug!(target:"sync", "New peer with unknown best hash {} ({}), searching for common ancestor.", info.best_hash, info.best_number);
self.peers.insert(who.clone(), PeerSync {
common_number: As::sa(0),
best_hash: info.best_hash,
best_number: info.best_number,
state: PeerSyncState::AncestorSearch(common_best, AncestorSearchState::ExponentialBackoff(As::sa(1))),
recently_announced: Default::default(),
});
Self::request_ancestry(protocol, who, common_best)
} else {
if our_best.is_zero() {
// We are at genesis, just start downloading
debug!(target:"sync", "New peer with best hash {} ({}).", info.best_hash, info.best_number);
self.peers.insert(who.clone(), PeerSync {
common_number: As::sa(0),
common_number: Zero::zero(),
best_hash: info.best_hash,
best_number: info.best_number,
state: PeerSyncState::Available,
recently_announced: Default::default(),
});
self.download_new(protocol, who)
} else {
let common_best = ::std::cmp::min(our_best, info.best_number);
debug!(target:"sync",
"New peer with unknown best hash {} ({}), searching for common ancestor.",
info.best_hash,
info.best_number
);
self.peers.insert(who.clone(), PeerSync {
common_number: Zero::zero(),
best_hash: info.best_hash,
best_number: info.best_number,
state: PeerSyncState::AncestorSearch(common_best, AncestorSearchState::ExponentialBackoff(One::one())),
recently_announced: Default::default(),
});
Self::request_ancestry(protocol, who, common_best)
}
},
(Ok(BlockStatus::Queued), _) | (Ok(BlockStatus::InChainWithState), _) | (Ok(BlockStatus::InChainPruned), _) => {
@@ -312,20 +319,22 @@ impl<B: BlockT> ChainSync<B> {
curr_block_num: NumberFor<B>,
block_hash_match: bool,
) -> Option<(AncestorSearchState<B>, NumberFor<B>)> {
let two = <NumberFor<B>>::one() + <NumberFor<B>>::one();
match state {
AncestorSearchState::ExponentialBackoff(next_distance_to_tip) => {
if block_hash_match && next_distance_to_tip == As::sa(1) {
if block_hash_match && next_distance_to_tip == One::one() {
// We found the ancestor in the first step so there is no need to execute binary search.
return None;
}
if block_hash_match {
let left = curr_block_num;
let right = left + next_distance_to_tip / As::sa(2);
let middle = left + (right - left) / As::sa(2);
let right = left + next_distance_to_tip / two;
let middle = left + (right - left) / two;
Some((AncestorSearchState::BinarySearch(left, right), middle))
} else {
let next_block_num = curr_block_num.checked_sub(&next_distance_to_tip).unwrap_or(As::sa(0));
let next_distance_to_tip = next_distance_to_tip * As::sa(2);
let next_block_num = curr_block_num.checked_sub(&next_distance_to_tip)
.unwrap_or_else(Zero::zero);
let next_distance_to_tip = next_distance_to_tip * two;
Some((AncestorSearchState::ExponentialBackoff(next_distance_to_tip), next_block_num))
}
},
@@ -339,7 +348,7 @@ impl<B: BlockT> ChainSync<B> {
right = curr_block_num;
}
assert!(right >= left);
let middle = left + (right - left) / As::sa(2);
let middle = left + (right - left) / two;
Some((AncestorSearchState::BinarySearch(left, right), middle))
},
}
@@ -372,7 +381,7 @@ impl<B: BlockT> ChainSync<B> {
peer.state = PeerSyncState::Available;
self.blocks.insert(start_block, blocks, who);
self.blocks
.drain(self.best_queued_number + As::sa(1))
.drain(self.best_queued_number + One::one())
.into_iter()
.map(|block_data| {
IncomingBlock {
@@ -418,7 +427,7 @@ impl<B: BlockT> ChainSync<B> {
if block_hash_match && peer.common_number < num {
peer.common_number = num;
}
if !block_hash_match && num == As::sa(0) {
if !block_hash_match && num.is_zero() {
trace!(target:"sync", "Ancestry search: genesis mismatch for peer {}", who);
protocol.report_peer(who.clone(), GENESIS_MISMATCH_REPUTATION_CHANGE);
protocol.disconnect_peer(who);
@@ -675,7 +684,7 @@ impl<B: BlockT> ChainSync<B> {
pub(crate) fn on_block_announce(&mut self, protocol: &mut Context<B>, who: PeerId, hash: B::Hash, header: &B::Header) {
let number = *header.number();
debug!(target: "sync", "Received block announcement with number {:?}", number);
if number <= As::sa(0) {
if number.is_zero() {
warn!(target: "sync", "Ignored invalid block announcement from {}: {}", who, hash);
return;
}
@@ -699,7 +708,7 @@ impl<B: BlockT> ChainSync<B> {
return;
}
if header.parent_hash() == &self.best_queued_hash || known_parent {
peer.common_number = number - As::sa(1);
peer.common_number = number - One::one();
} else if known {
peer.common_number = number
}
@@ -769,7 +778,7 @@ impl<B: BlockT> ChainSync<B> {
Err(e) => {
debug!(target:"sync", "Error reading blockchain: {:?}", e);
self.best_queued_hash = self.genesis_hash;
self.best_queued_number = As::sa(0);
self.best_queued_number = Zero::zero();
}
}
let ids: Vec<PeerId> = self.peers.drain().map(|(id, _)| id).collect();
@@ -839,7 +848,7 @@ impl<B: BlockT> ChainSync<B> {
from: message::FromBlock::Number(range.start),
to: None,
direction: message::Direction::Ascending,
max: Some((range.end - range.start).as_() as u32),
max: Some((range.end - range.start).saturated_into::<u32>()),
};
peer.state = PeerSyncState::DownloadingNew(range.start);
protocol.send_block_request(who, request);
+10 -11
View File
@@ -15,6 +15,7 @@
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use serde::Deserialize;
use std::{convert::TryFrom, fmt::Debug};
use primitives::U256;
use runtime_primitives::traits;
@@ -34,30 +35,28 @@ pub enum NumberOrHex<Number> {
Hex(U256),
}
impl<Number: traits::As<u64>> NumberOrHex<Number> {
impl<Number: TryFrom<u64> + From<u32> + Debug + PartialOrd> NumberOrHex<Number> {
/// Attempts to convert into concrete block number.
///
/// Fails in case hex number is too big.
pub fn to_number(self) -> Result<Number, String> {
let num: u64 = match self {
NumberOrHex::Number(n) => n.as_(),
let num = match self {
NumberOrHex::Number(n) => n,
NumberOrHex::Hex(h) => {
// FIXME #1377 this only supports `u64` since `BlockNumber`
// is `As<u64>` we could possibly go with `u128`.
let l = h.low_u64();
if U256::from(l) != h {
return Err(format!("`{}` does not fit into the block number type.", h));
return Err(format!("`{}` does not fit into u64 type; unsupported for now.", h))
} else {
l
Number::try_from(l)
.map_err(|_| format!("`{}` does not fit into block number type.", h))?
}
},
};
// FIXME <2329>: Database seems to limit the block number to u32 for no reason
if num > u32::max_value() as u64 {
Err(format!("`{}` > u32::max_value(), the max block number is u32.", num))
} else {
Ok(traits::As::sa(num))
if num > Number::from(u32::max_value()) {
return Err(format!("`{:?}` > u32::max_value(), the max block number is u32.", num))
}
Ok(num)
}
}
+7 -4
View File
@@ -33,7 +33,10 @@ use primitives::storage::{self, StorageKey, StorageData, StorageChangeSet};
use crate::rpc::Result as RpcResult;
use crate::rpc::futures::{stream, Future, Sink, Stream};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header, ProvideRuntimeApi, As, NumberFor};
use runtime_primitives::traits::{
Block as BlockT, Header, ProvideRuntimeApi, NumberFor,
SaturatedConversion
};
use runtime_version::RuntimeVersion;
use state_machine::{self, ExecutionStrategy};
@@ -229,7 +232,7 @@ impl<B, E, Block: BlockT, RA> State<B, E, Block, RA> where
};
// check if we can filter blocks-with-changes from some (sub)range using changes tries
let changes_trie_range = self.client.max_key_changes_range(from_number, BlockId::Hash(to.hash()))?;
let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).as_() as usize);
let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).saturated_into::<usize>());
let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin);
Ok(QueryStorageRange {
hashes: blocks,
@@ -281,7 +284,7 @@ impl<B, E, Block: BlockT, RA> State<B, E, Block, RA> where
) -> Result<()> {
let (begin, end) = match range.filtered_range {
Some(ref filtered_range) => (
range.first_number + As::sa(filtered_range.start as u64),
range.first_number + filtered_range.start.saturated_into(),
BlockId::Hash(range.hashes[filtered_range.end - 1].clone())
),
None => return Ok(()),
@@ -293,7 +296,7 @@ impl<B, E, Block: BlockT, RA> State<B, E, Block, RA> where
if last_block == Some(block) {
continue;
}
let block_hash = range.hashes[(block - range.first_number).as_() as usize].clone();
let block_hash = range.hashes[(block - range.first_number).saturated_into::<usize>()].clone();
let id = BlockId::Hash(block_hash);
let value_at_block = self.client.storage(&id, key)?;
changes_map.entry(block)
+7 -7
View File
@@ -21,7 +21,7 @@ use futures::Future;
use log::{info, warn};
use runtime_primitives::generic::{SignedBlock, BlockId};
use runtime_primitives::traits::{As, Block, Header, NumberFor};
use runtime_primitives::traits::{SaturatedConversion, Zero, One, Block, Header, NumberFor};
use consensus_common::import_queue::{ImportQueue, IncomingBlock, Link};
use network::message;
@@ -50,7 +50,7 @@ pub fn export_blocks<F, E, W>(
let mut block = from;
let last = match to {
Some(v) if v == As::sa(0) => As::sa(1),
Some(v) if v.is_zero() => One::one(),
Some(v) => v,
None => client.info()?.chain.best_number,
};
@@ -66,8 +66,8 @@ pub fn export_blocks<F, E, W>(
});
info!("Exporting blocks from #{} to #{}", block, last);
if !json {
let last_: u64 = last.as_();
let block_: u64 = block.as_();
let last_: u64 = last.saturated_into::<u64>();
let block_: u64 = block.saturated_into::<u64>();
let len: u64 = last_ - block_ + 1;
output.write(&len.encode())?;
}
@@ -87,13 +87,13 @@ pub fn export_blocks<F, E, W>(
},
None => break,
}
if block.as_() % 10000 == 0 {
if (block % 10000.into()).is_zero() {
info!("#{}", block);
}
if block == last {
break;
}
block += As::sa(1);
block += One::one();
}
Ok(())
}
@@ -202,7 +202,7 @@ pub fn revert_chain<F>(
let reverted = client.revert(blocks)?;
let info = client.info()?.chain;
if reverted.as_() == 0 {
if reverted.is_zero() {
info!("There aren't any non-finalized blocks to revert.");
} else {
info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash);
+5 -2
View File
@@ -40,7 +40,7 @@ use log::{info, warn, debug};
use parity_codec::{Encode, Decode};
use primitives::Pair;
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Header, As};
use runtime_primitives::traits::{Header, SaturatedConversion};
use substrate_executor::NativeExecutor;
use tel::{telemetry, SUBSTRATE_INFO};
@@ -162,7 +162,10 @@ impl<Components: components::Components> Service<Components> {
let version = config.full_version();
info!("Highest known block at #{}", chain_info.best_number);
telemetry!(SUBSTRATE_INFO; "node.start"; "height" => chain_info.best_number.as_(), "best" => ?chain_info.best_hash);
telemetry!(SUBSTRATE_INFO; "node.start";
"height" => chain_info.best_number.saturated_into::<u64>(),
"best" => ?chain_info.best_hash
);
let network_protocol = <Components::Factory>::build_network_protocol(&config)?;
let transaction_pool = Arc::new(
+5 -6
View File
@@ -36,7 +36,6 @@ use service::{
};
use network::{multiaddr, Multiaddr, SyncProvider, ManageNetwork};
use network::config::{NetworkConfiguration, NodeKeyConfig, Secret, NonReservedPeerMode};
use sr_primitives::traits::As;
use sr_primitives::generic::BlockId;
use consensus::{ImportBlock, BlockImport};
@@ -229,7 +228,7 @@ where
E: Fn(&F::FullService) -> FactoryExtrinsic<F>,
{
const NUM_NODES: u32 = 10;
const NUM_BLOCKS: usize = 512;
const NUM_BLOCKS: u32 = 512;
let temp = TempDir::new("substrate-sync-test").expect("Error creating test dir");
let mut network = TestNet::<F>::new(&temp, spec.clone(), NUM_NODES, 0, vec![], 30500);
info!("Checking block sync");
@@ -249,7 +248,7 @@ where
service.network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer");
}
network.run_until_all_full(|_index, service|
service.client().info().unwrap().chain.best_number == As::sa(NUM_BLOCKS as u64)
service.client().info().unwrap().chain.best_number == NUM_BLOCKS.into()
);
info!("Checking extrinsic propagation");
let first_service = network.full_nodes[0].1.clone();
@@ -265,7 +264,7 @@ pub fn consensus<F>(spec: FactoryChainSpec<F>, authorities: Vec<String>)
F: ServiceFactory,
{
const NUM_NODES: u32 = 20;
const NUM_BLOCKS: u64 = 200;
const NUM_BLOCKS: u32 = 200;
let temp = TempDir::new("substrate-conensus-test").expect("Error creating test dir");
let mut network = TestNet::<F>::new(&temp, spec.clone(), NUM_NODES / 2, 0, authorities, 30600);
info!("Checking consensus");
@@ -277,7 +276,7 @@ pub fn consensus<F>(spec: FactoryChainSpec<F>, authorities: Vec<String>)
service.network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer");
}
network.run_until_all_full(|_index, service| {
service.client().info().unwrap().chain.finalized_number >= As::sa(NUM_BLOCKS / 2)
service.client().info().unwrap().chain.finalized_number >= (NUM_BLOCKS / 2).into()
});
info!("Adding more peers");
network.insert_nodes(&temp, NUM_NODES / 2, 0, vec![]);
@@ -285,6 +284,6 @@ pub fn consensus<F>(spec: FactoryChainSpec<F>, authorities: Vec<String>)
service.network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer");
}
network.run_until_all_full(|_index, service|
service.client().info().unwrap().chain.finalized_number >= As::sa(NUM_BLOCKS)
service.client().info().unwrap().chain.finalized_number >= NUM_BLOCKS.into()
);
}
@@ -22,8 +22,8 @@ use std::fmt;
use rstd::prelude::*;
use runtime_io::blake2_256;
use crate::codec::{Decode, Encode, Input, Compact};
use crate::traits::{self, Member, SimpleArithmetic, MaybeDisplay, CurrentHeight, BlockNumberToHash, Lookup,
Checkable, Extrinsic};
use crate::traits::{self, Member, SimpleArithmetic, MaybeDisplay, CurrentHeight, BlockNumberToHash,
Lookup, Checkable, Extrinsic, SaturatedConversion};
use super::{CheckedExtrinsic, Era};
const TRANSACTION_VERSION: u8 = 1;
@@ -84,7 +84,8 @@ where
fn check(self, context: &Context) -> Result<Self::Checked, &'static str> {
Ok(match self.signature {
Some((signed, signature, index, era)) => {
let h = context.block_number_to_hash(BlockNumber::sa(era.birth(context.current_height().as_())))
let current_u64 = context.current_height().saturated_into::<u64>();
let h = context.block_number_to_hash(era.birth(current_u64).saturated_into())
.ok_or("transaction birth block ancient")?;
let signed = context.lookup(signed)?;
let raw_payload = (index, self.function, era, h);
@@ -22,8 +22,10 @@ use std::fmt;
use rstd::prelude::*;
use runtime_io::blake2_256;
use crate::codec::{Decode, Encode, Input};
use crate::traits::{self, Member, SimpleArithmetic, MaybeDisplay, CurrentHeight, BlockNumberToHash, Lookup,
Checkable, Extrinsic};
use crate::traits::{
self, Member, SimpleArithmetic, MaybeDisplay, CurrentHeight, BlockNumberToHash,
Lookup, Checkable, Extrinsic, SaturatedConversion
};
use super::{CheckedExtrinsic, Era};
const TRANSACTION_VERSION: u8 = 1;
@@ -83,7 +85,8 @@ where
fn check(self, context: &Context) -> Result<Self::Checked, &'static str> {
Ok(match self.signature {
Some((signed, signature, index, era)) => {
let h = context.block_number_to_hash(BlockNumber::sa(era.birth(context.current_height().as_())))
let current_u64 = context.current_height().saturated_into::<u64>();
let h = context.block_number_to_hash(era.birth(current_u64).saturated_into())
.ok_or("transaction birth block ancient")?;
let signed = context.lookup(signed)?;
let raw_payload = (index, self.function, era, h);
+30 -28
View File
@@ -29,8 +29,7 @@ pub use serde;
#[cfg(feature = "std")]
pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay};
use rstd::prelude::*;
use rstd::ops;
use rstd::{prelude::*, ops};
use substrate_primitives::{crypto, ed25519, sr25519, hash::{H256, H512}};
use codec::{Encode, Decode};
@@ -38,6 +37,8 @@ use codec::{Encode, Decode};
pub mod testing;
pub mod traits;
use traits::{SaturatedConversion, UniqueSaturatedInto};
pub mod generic;
pub mod transaction_validity;
@@ -159,27 +160,30 @@ impl Permill {
impl<N> ops::Mul<N> for Permill
where
N: Clone + traits::As<u64> + ops::Rem<N, Output=N> + ops::Div<N, Output=N>
+ ops::Mul<N, Output=N> + ops::Add<N, Output=N>,
N: Clone + From<u32> + UniqueSaturatedInto<u32> + ops::Rem<N, Output=N>
+ ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N>,
{
type Output = N;
fn mul(self, b: N) -> Self::Output {
let million = <N as traits::As<u64>>::sa(1_000_000);
let part = <N as traits::As<u64>>::sa(self.0 as u64);
let million: N = 1_000_000.into();
let part: N = self.0.into();
let rem_multiplied_divided = {
let rem = b.clone().rem(million.clone());
// `rem` is inferior to one million, thus it fits into u64
let rem_u64: u64 = rem.as_();
// `rem` is inferior to one million, thus it fits into u32
let rem_u32 = rem.saturated_into::<u32>();
// `self` and `rem` are inferior to one million, thus the product fits into u64
let rem_multiplied_u64 = rem_u64 * self.0 as u64;
// `self` and `rem` are inferior to one million, thus the product is less than 10^12
// and fits into u64
let rem_multiplied_u64 = rem_u32 as u64 * self.0 as u64;
let rem_multiplied_divided_u64 = rem_multiplied_u64 / 1_000_000;
// `rem_multiplied_u64` is less than 10^12 therefore divided by a million it fits into
// u32
let rem_multiplied_divided_u32 = (rem_multiplied_u64 / 1_000_000) as u32;
// `rem_multiplied_divided` is inferior to b, thus it can be converted back to N type
traits::As::sa(rem_multiplied_divided_u64)
rem_multiplied_divided_u32.into()
};
(b / million) * part + rem_multiplied_divided
@@ -248,27 +252,30 @@ impl Perbill {
impl<N> ops::Mul<N> for Perbill
where
N: Clone + traits::As<u64> + ops::Rem<N, Output=N> + ops::Div<N, Output=N>
+ ops::Mul<N, Output=N> + ops::Add<N, Output=N>
N: Clone + From<u32> + UniqueSaturatedInto<u32> + ops::Rem<N, Output=N>
+ ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N>,
{
type Output = N;
fn mul(self, b: N) -> Self::Output {
let billion = <N as traits::As<u64>>::sa(1_000_000_000);
let part = <N as traits::As<u64>>::sa(self.0 as u64);
let billion: N = 1_000_000_000.into();
let part: N = self.0.into();
let rem_multiplied_divided = {
let rem = b.clone().rem(billion.clone());
// `rem` is inferior to one billion, thus it fits into u64
let rem_u64: u64 = rem.as_();
// `rem` is inferior to one billion, thus it fits into u32
let rem_u32 = rem.saturated_into::<u32>();
// `self` and `rem` are inferior to one billion, thus the product fits into u64
let rem_multiplied_u64 = rem_u64 * self.0 as u64;
// `self` and `rem` are inferior to one billion, thus the product is less than 10^18
// and fits into u64
let rem_multiplied_u64 = rem_u32 as u64 * self.0 as u64;
let rem_multiplied_divided_u64 = rem_multiplied_u64 / 1_000_000_000;
// `rem_multiplied_u64` is less than 10^18 therefore divided by a billion it fits into
// u32
let rem_multiplied_divided_u32 = (rem_multiplied_u64 / 1_000_000_000) as u32;
// `rem_multiplied_divided` is inferior to b, thus it can be converted back to N type
traits::As::sa(rem_multiplied_divided_u64)
rem_multiplied_divided_u32.into()
};
(b / billion) * part + rem_multiplied_divided
@@ -918,13 +925,8 @@ mod tests {
}
#[test]
#[should_panic]
fn per_things_operate_in_output_type() {
use super::Perbill;
assert_eq!(Perbill::one() * 255_u64, 255);
// panics
assert_ne!(Perbill::one() * 255_u8, 255);
assert_eq!(super::Perbill::one() * 255_u64, 255);
}
#[test]
+121 -49
View File
@@ -17,7 +17,7 @@
//! Primitives for the runtime modules.
use rstd::prelude::*;
use rstd::{self, result, marker::PhantomData};
use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}};
use runtime_io;
#[cfg(feature = "std")] use std::fmt::{Debug, Display};
#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned};
@@ -27,7 +27,7 @@ use crate::transaction_validity::TransactionValidity;
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
CheckedShl, CheckedShr, Saturating
CheckedShl, CheckedShr
};
use rstd::ops::{
Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign,
@@ -157,71 +157,143 @@ impl<T> Convert<T, T> for Identity {
fn convert(a: T) -> T { a }
}
/// Simple trait similar to `Into`, except that it can be used to convert numerics between each
/// other.
pub trait As<T> {
/// Convert forward (ala `Into::into`).
fn as_(self) -> T;
/// Convert backward (ala `From::from`).
fn sa(_: T) -> Self;
}
macro_rules! impl_numerics {
( $( $t:ty ),* ) => {
$(
impl_numerics!($t: u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize,);
)*
};
( $f:ty : $t:ty, $( $rest:ty, )* ) => {
impl As<$t> for $f {
fn as_(self) -> $t { self as $t }
fn sa(t: $t) -> Self { t as Self }
}
impl_numerics!($f: $( $rest, )*);
};
( $f:ty : ) => {}
}
impl_numerics!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
/// A meta trait for arithmetic.
///
/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
/// be able to represent at least `u32` values without loss, hence the trait implies `From<u32>`
/// and smaller ints. All other conversions are fallible.
pub trait SimpleArithmetic:
Zero + One + IntegerSquareRoot + As<u64> +
Zero + One + IntegerSquareRoot +
From<u8> + From<u16> + From<u32> + TryInto<u8> + TryInto<u16> + TryInto<u32> +
TryFrom<u64> + TryInto<u64> + TryFrom<u128> + TryInto<u128> + TryFrom<usize> + TryInto<usize> +
UniqueSaturatedInto<u8> + UniqueSaturatedInto<u16> + UniqueSaturatedInto<u32> +
UniqueSaturatedFrom<u64> + UniqueSaturatedInto<u64> + UniqueSaturatedFrom<u128> + UniqueSaturatedInto<u128> +
Add<Self, Output = Self> + AddAssign<Self> +
Sub<Self, Output = Self> + SubAssign<Self> +
Mul<Self, Output = Self> + MulAssign<Self> +
Div<Self, Output = Self> + DivAssign<Self> +
Rem<Self, Output = Self> + RemAssign<Self> +
Shl<u32, Output = Self> + Shr<u32, Output = Self> +
CheckedShl +
CheckedShr +
CheckedAdd +
CheckedSub +
CheckedMul +
CheckedDiv +
Saturating +
PartialOrd<Self> + Ord + Bounded +
HasCompact
CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv +
Saturating + PartialOrd<Self> + Ord + Bounded +
HasCompact + Sized
{}
impl<T:
Zero + One + IntegerSquareRoot + As<u64> +
Zero + One + IntegerSquareRoot +
From<u8> + From<u16> + From<u32> + TryInto<u8> + TryInto<u16> + TryInto<u32> +
TryFrom<u64> + TryInto<u64> + TryFrom<u128> + TryInto<u128> + TryFrom<usize> + TryInto<usize> +
UniqueSaturatedInto<u8> + UniqueSaturatedInto<u16> + UniqueSaturatedInto<u32> +
UniqueSaturatedFrom<u64> + UniqueSaturatedInto<u64> + UniqueSaturatedFrom<u128> +
UniqueSaturatedInto<u128> + UniqueSaturatedFrom<usize> + UniqueSaturatedInto<usize> +
Add<Self, Output = Self> + AddAssign<Self> +
Sub<Self, Output = Self> + SubAssign<Self> +
Mul<Self, Output = Self> + MulAssign<Self> +
Div<Self, Output = Self> + DivAssign<Self> +
Rem<Self, Output = Self> + RemAssign<Self> +
Shl<u32, Output = Self> + Shr<u32, Output = Self> +
CheckedShl +
CheckedShr +
CheckedAdd +
CheckedSub +
CheckedMul +
CheckedDiv +
Saturating +
PartialOrd<Self> + Ord + Bounded +
HasCompact
CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv +
Saturating + PartialOrd<Self> + Ord + Bounded +
HasCompact + Sized
> SimpleArithmetic for T {}
/// Just like `From` except that if the source value is too big to fit into the destination type
/// then it'll saturate the destination.
pub trait UniqueSaturatedFrom<T: Sized>: Sized {
/// Convert from a value of `T` into an equivalent instance of `Self`.
fn unique_saturated_from(t: T) -> Self;
}
/// Just like `Into` except that if the source value is too big to fit into the destination type
/// then it'll saturate the destination.
pub trait UniqueSaturatedInto<T: Sized>: Sized {
/// Consume self to return an equivalent value of `T`.
fn unique_saturated_into(self) -> T;
}
impl<T: Sized, S: TryFrom<T> + Bounded + Sized> UniqueSaturatedFrom<T> for S {
fn unique_saturated_from(t: T) -> Self {
S::try_from(t).unwrap_or_else(|_| Bounded::max_value())
}
}
impl<T: Bounded + Sized, S: TryInto<T> + Sized> UniqueSaturatedInto<T> for S {
fn unique_saturated_into(self) -> T {
self.try_into().unwrap_or_else(|_| Bounded::max_value())
}
}
/// Simple trait to use checked mul and max value to give a saturated mul operation over
/// supported types.
pub trait Saturating {
/// Saturated addition - if the product can't fit in the type then just use max-value.
fn saturating_add(self, o: Self) -> Self;
/// Saturated subtraction - if the product can't fit in the type then just use max-value.
fn saturating_sub(self, o: Self) -> Self;
/// Saturated multiply - if the product can't fit in the type then just use max-value.
fn saturating_mul(self, o: Self) -> Self;
}
impl<T: CheckedMul + Bounded + num_traits::Saturating> Saturating for T {
fn saturating_add(self, o: Self) -> Self {
<Self as num_traits::Saturating>::saturating_add(self, o)
}
fn saturating_sub(self, o: Self) -> Self {
<Self as num_traits::Saturating>::saturating_sub(self, o)
}
fn saturating_mul(self, o: Self) -> Self {
self.checked_mul(&o).unwrap_or_else(Bounded::max_value)
}
}
/// Convenience type to work around the highly unergonomic syntax needed
/// to invoke the functions of overloaded generic traits, in this case
/// `SaturatedFrom` and `SaturatedInto`.
pub trait SaturatedConversion {
/// Convert from a value of `T` into an equivalent instance of `Self`.
///
/// This just uses `UniqueSaturatedFrom` internally but with this
/// variant you can provide the destination type using turbofish syntax
/// in case Rust happens not to assume the correct type.
fn saturated_from<T>(t: T) -> Self where Self: UniqueSaturatedFrom<T> {
<Self as UniqueSaturatedFrom<T>>::unique_saturated_from(t)
}
/// Consume self to return an equivalent value of `T`.
///
/// This just uses `UniqueSaturatedInto` internally but with this
/// variant you can provide the destination type using turbofish syntax
/// in case Rust happens not to assume the correct type.
fn saturated_into<T>(self) -> T where Self: UniqueSaturatedInto<T> {
<Self as UniqueSaturatedInto<T>>::unique_saturated_into(self)
}
}
impl<T: Sized> SaturatedConversion for T {}
/// Convenience type to work around the highly unergonomic syntax needed
/// to invoke the functions of overloaded generic traits, in this case
/// `TryFrom` and `TryInto`.
pub trait CheckedConversion {
/// Convert from a value of `T` into an equivalent instance of `Option<Self>`.
///
/// This just uses `TryFrom` internally but with this
/// variant you can provide the destination type using turbofish syntax
/// in case Rust happens not to assume the correct type.
fn checked_from<T>(t: T) -> Option<Self> where Self: TryFrom<T> {
<Self as TryFrom<T>>::try_from(t).ok()
}
/// Consume self to return `Some` equivalent value of `Option<T>`.
///
/// This just uses `TryInto` internally but with this
/// variant you can provide the destination type using turbofish syntax
/// in case Rust happens not to assume the correct type.
fn checked_into<T>(self) -> Option<T> where Self: TryInto<T> {
<Self as TryInto<T>>::try_into(self).ok()
}
}
impl<T: Sized> CheckedConversion for T {}
/// Trait for things that can be clear (have no bits set). For numeric types, essentially the same
/// as `Zero`.
pub trait Clear {
@@ -51,8 +51,7 @@ pub fn prune<S: Storage<H>, H: Hasher, F: FnMut(H::Out)>(
min_blocks_to_keep: u64,
current_block: &AnchorBlockId<H::Out>,
mut remove_trie_node: F,
)
{
) {
// select range for pruning
let (first, last) = match pruning_range(config, min_blocks_to_keep, current_block.number) {
Some((first, last)) => (first, last),
+1
View File
@@ -2453,6 +2453,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"sr-version 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
@@ -34,7 +34,7 @@ use futures::sync::mpsc;
use parking_lot::{Mutex, RwLock};
use sr_primitives::{
generic::BlockId,
traits::{self, As},
traits::{self, SaturatedConversion},
transaction_validity::{TransactionValidity, TransactionTag as Tag},
};
@@ -138,7 +138,9 @@ impl<B: ChainApi> Pool<B> {
priority,
requires,
provides,
valid_till: block_number.as_().saturating_add(longevity),
valid_till: block_number
.saturated_into::<u64>()
.saturating_add(longevity),
})
},
TransactionValidity::Invalid(e) => {
@@ -337,7 +339,7 @@ impl<B: ChainApi> Pool<B> {
pub fn clear_stale(&self, at: &BlockId<B::Block>) -> Result<(), B::Error> {
let block_number = self.api.block_id_to_number(at)?
.ok_or_else(|| error::ErrorKind::Msg(format!("Invalid block id: {:?}", at)).into())?
.as_();
.saturated_into::<u64>();
let now = time::Instant::now();
let to_remove = {
self.ready()
+1
View File
@@ -2596,6 +2596,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"sr-version 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
+2 -2
View File
@@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node"),
impl_name: create_runtime_str!("substrate-node"),
authoring_version: 10,
spec_version: 80,
impl_version: 82,
spec_version: 81,
impl_version: 81,
apis: RUNTIME_API_VERSIONS,
};
+1
View File
@@ -2731,6 +2731,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"sr-version 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
+13 -15
View File
@@ -53,7 +53,7 @@ pub use timestamp;
use rstd::{result, prelude::*};
use srml_support::storage::StorageValue;
use srml_support::{decl_storage, decl_module};
use primitives::traits::{As, Zero};
use primitives::traits::{SaturatedConversion, Saturating, Zero, One};
use timestamp::OnTimestampSet;
#[cfg(feature = "std")]
use timestamp::TimestampInherentData;
@@ -154,7 +154,7 @@ pub trait Trait: timestamp::Trait {
decl_storage! {
trait Store for Module<T: Trait> as Aura {
/// The last timestamp.
LastTimestamp get(last) build(|_| T::Moment::sa(0)): T::Moment;
LastTimestamp get(last) build(|_| 0.into()): T::Moment;
}
}
@@ -192,43 +192,41 @@ impl AuraReport {
impl<T: Trait> Module<T> {
/// Determine the Aura slot-duration based on the Timestamp module configuration.
pub fn slot_duration() -> u64 {
pub fn slot_duration() -> T::Moment {
// we double the minimum block-period so each author can always propose within
// the majority of its slot.
<timestamp::Module<T>>::minimum_period().as_().saturating_mul(2)
<timestamp::Module<T>>::minimum_period().saturating_mul(2.into())
}
fn on_timestamp_set<H: HandleReport>(now: T::Moment, slot_duration: T::Moment) {
let last = Self::last();
<Self as Store>::LastTimestamp::put(now.clone());
if last == T::Moment::zero() {
if last.is_zero() {
return;
}
assert!(slot_duration > T::Moment::zero(), "Aura slot duration cannot be zero.");
assert!(!slot_duration.is_zero(), "Aura slot duration cannot be zero.");
let last_slot = last / slot_duration.clone();
let first_skipped = last_slot.clone() + T::Moment::sa(1);
let first_skipped = last_slot.clone() + One::one();
let cur_slot = now / slot_duration;
assert!(last_slot < cur_slot, "Only one block may be authored per slot.");
if cur_slot == first_skipped { return }
let slot_to_usize = |slot: T::Moment| { slot.as_() as usize };
let skipped_slots = cur_slot - last_slot - T::Moment::sa(1);
let skipped_slots = cur_slot - last_slot - One::one();
H::handle_report(AuraReport {
start_slot: slot_to_usize(first_skipped),
skipped: slot_to_usize(skipped_slots),
start_slot: first_skipped.saturated_into::<usize>(),
skipped: skipped_slots.saturated_into::<usize>(),
})
}
}
impl<T: Trait> OnTimestampSet<T::Moment> for Module<T> {
fn on_timestamp_set(moment: T::Moment) {
Self::on_timestamp_set::<T::HandleReport>(moment, T::Moment::sa(Self::slot_duration()))
Self::on_timestamp_set::<T::HandleReport>(moment, Self::slot_duration())
}
}
@@ -265,9 +263,9 @@ impl<T: Trait> ProvideInherent for Module<T> {
_ => return Ok(()),
};
let timestamp_based_slot = timestamp.as_() / Self::slot_duration();
let timestamp_based_slot = timestamp / Self::slot_duration();
let seal_slot = data.aura_inherent_data()?;
let seal_slot = data.aura_inherent_data()?.saturated_into();
if timestamp_based_slot == seal_slot {
Ok(())
+4 -6
View File
@@ -22,8 +22,8 @@ pub use timestamp;
use rstd::{result, prelude::*};
use srml_support::{decl_storage, decl_module};
use primitives::traits::As;
use timestamp::{OnTimestampSet, Trait};
use primitives::traits::{SaturatedConversion, Saturating};
#[cfg(feature = "std")]
use timestamp::TimestampInherentData;
use parity_codec::Decode;
@@ -116,10 +116,10 @@ decl_module! {
impl<T: Trait> Module<T> {
/// Determine the BABE slot duration based on the Timestamp module configuration.
pub fn slot_duration() -> u64 {
pub fn slot_duration() -> T::Moment {
// we double the minimum block-period so each author can always propose within
// the majority of their slot.
<timestamp::Module<T>>::minimum_period().as_().saturating_mul(2)
<timestamp::Module<T>>::minimum_period().saturating_mul(2.into())
}
}
@@ -142,10 +142,8 @@ impl<T: Trait> ProvideInherent for Module<T> {
_ => return Ok(()),
};
let timestamp_based_slot = timestamp.as_() / Self::slot_duration();
let timestamp_based_slot = (timestamp / Self::slot_duration()).saturated_into::<u64>();
let seal_slot = data.babe_inherent_data()?;
if timestamp_based_slot == seal_slot {
Ok(())
} else {
+15 -12
View File
@@ -155,7 +155,7 @@ use srml_support::traits::{
};
use srml_support::dispatch::Result;
use primitives::traits::{
Zero, SimpleArithmetic, As, StaticLookup, Member, CheckedAdd, CheckedSub,
Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub,
MaybeSerializeDebug, Saturating
};
use system::{IsDeadAccount, OnNewAccount, ensure_signed};
@@ -167,7 +167,8 @@ pub use self::imbalances::{PositiveImbalance, NegativeImbalance};
pub trait Subtrait<I: Instance = DefaultInstance>: system::Trait {
/// The balance of an account.
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + MaybeSerializeDebug;
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy +
MaybeSerializeDebug + From<Self::BlockNumber>;
/// A function that is invoked when the free-balance has fallen below the existential deposit and
/// has been reduced to zero.
@@ -181,7 +182,8 @@ pub trait Subtrait<I: Instance = DefaultInstance>: system::Trait {
pub trait Trait<I: Instance = DefaultInstance>: system::Trait {
/// The balance of an account.
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + MaybeSerializeDebug;
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy +
MaybeSerializeDebug + From<Self::BlockNumber>;
/// A function that is invoked when the free-balance has fallen below the existential deposit and
/// has been reduced to zero.
@@ -236,10 +238,12 @@ pub struct VestingSchedule<Balance> {
pub per_block: Balance,
}
impl<Balance: SimpleArithmetic + Copy + As<u64>> VestingSchedule<Balance> {
impl<Balance: SimpleArithmetic + Copy> VestingSchedule<Balance> {
/// Amount locked at block `n`.
pub fn locked_at<BlockNumber: As<u64>>(&self, n: BlockNumber) -> Balance {
if let Some(x) = Balance::sa(n.as_()).checked_mul(&self.per_block) {
pub fn locked_at<BlockNumber>(&self, n: BlockNumber) -> Balance
where Balance: From<BlockNumber>
{
if let Some(x) = Balance::from(n).checked_mul(&self.per_block) {
self.offset.max(x) - x
} else {
Zero::zero()
@@ -276,10 +280,8 @@ decl_storage! {
/// Information regarding the vesting of a given account.
pub Vesting get(vesting) build(|config: &GenesisConfig<T, I>| {
config.vesting.iter().filter_map(|&(ref who, begin, length)| {
let begin: u64 = begin.as_();
let length: u64 = length.as_();
let begin: T::Balance = As::sa(begin);
let length: T::Balance = As::sa(length);
let begin = <T::Balance as From<T::BlockNumber>>::from(begin);
let length = <T::Balance as From<T::BlockNumber>>::from(length);
config.balances.iter()
.find(|&&(ref w, _)| w == who)
@@ -380,7 +382,8 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
/// Get the amount that is currently being vested and cannot be transferred out of this account.
pub fn vesting_balance(who: &T::AccountId) -> T::Balance {
if let Some(v) = Self::vesting(who) {
Self::free_balance(who).min(v.locked_at(<system::Module<T>>::block_number()))
Self::free_balance(who)
.min(v.locked_at::<T::BlockNumber>(<system::Module<T>>::block_number()))
} else {
Zero::zero()
}
@@ -1013,7 +1016,7 @@ where
impl<T: Trait<I>, I: Instance> MakePayment<T::AccountId> for Module<T, I> {
fn make_payment(transactor: &T::AccountId, encoded_len: usize) -> Result {
let encoded_len = <T::Balance as As<u64>>::sa(encoded_len as u64);
let encoded_len = T::Balance::from(encoded_len as u32);
let transaction_fee = Self::transaction_base_fee() + Self::transaction_byte_fee() * encoded_len;
let imbalance = Self::withdraw(
transactor,
+2 -2
View File
@@ -140,10 +140,10 @@ impl<T: Trait> AccountDb<T> for DirectAccountDb {
for (k, v) in changed.storage.into_iter() {
if let Some(value) = child::get_raw(&new_info.trie_id[..], &blake2_256(&k)) {
new_info.storage_size -= value.len() as u64;
new_info.storage_size -= value.len() as u32;
}
if let Some(value) = v {
new_info.storage_size += value.len() as u64;
new_info.storage_size += value.len() as u32;
child::put_raw(&new_info.trie_id[..], &blake2_256(&k), &value[..]);
} else {
child::kill(&new_info.trie_id[..], &blake2_256(&k));
+4 -5
View File
@@ -16,7 +16,7 @@
use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf};
use runtime_primitives::BLOCK_FULL;
use runtime_primitives::traits::{As, CheckedMul, CheckedSub, Zero};
use runtime_primitives::traits::{CheckedMul, CheckedSub, Zero, SaturatedConversion};
use srml_support::{StorageValue, traits::{OnUnbalanced, ExistenceRequirement, WithdrawReason, Currency, Imbalance}};
#[cfg(test)]
@@ -212,7 +212,7 @@ pub fn buy_gas<T: Trait>(
// Buy the specified amount of gas.
let gas_price = <Module<T>>::gas_price();
let cost = <T::Gas as As<BalanceOf<T>>>::as_(gas_limit.clone())
let cost = gas_limit.clone().into()
.checked_mul(&gas_price)
.ok_or("overflow multiplying gas limit by price")?;
@@ -248,7 +248,7 @@ pub fn refund_unused_gas<T: Trait>(
<GasSpent<T>>::mutate(|block_gas_spent| *block_gas_spent += gas_spent);
// Refund gas left by the price it was bought at.
let refund = <T::Gas as As<BalanceOf<T>>>::as_(gas_left) * gas_meter.gas_price;
let refund = gas_left.into() * gas_meter.gas_price;
let refund_imbalance = T::Currency::deposit_creating(transactor, refund);
if let Ok(imbalance) = imbalance.offset(refund_imbalance) {
T::GasPayment::on_unbalanced(imbalance);
@@ -258,8 +258,7 @@ pub fn refund_unused_gas<T: Trait>(
/// A little handy utility for converting a value in balance units into approximate value in gas units
/// at the given gas price.
pub fn approx_gas_for_balance<T: Trait>(gas_price: BalanceOf<T>, balance: BalanceOf<T>) -> T::Gas {
let amount_in_gas: BalanceOf<T> = balance / gas_price;
<T::Gas as As<BalanceOf<T>>>::sa(amount_in_gas)
(balance / gas_price).saturated_into::<T::Gas>()
}
/// A simple utility macro that helps to match against a
+26 -26
View File
@@ -94,10 +94,9 @@ use crate::account_db::{AccountDb, DirectAccountDb};
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
use substrate_primitives::crypto::UncheckedFrom;
use rstd::prelude::*;
use rstd::marker::PhantomData;
use rstd::{prelude::*, marker::PhantomData, convert::TryFrom};
use parity_codec::{Codec, Encode, Decode};
use runtime_primitives::traits::{Hash, As, SimpleArithmetic, Bounded, StaticLookup, Zero};
use runtime_primitives::traits::{Hash, SimpleArithmetic, Bounded, StaticLookup, Zero};
use srml_support::dispatch::{Result, Dispatchable};
use srml_support::{Parameter, StorageMap, StorageValue, decl_module, decl_event, decl_storage, storage::child};
use srml_support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency};
@@ -188,7 +187,7 @@ pub struct RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
/// Unique ID for the subtree encoded as a bytes vector.
pub trie_id: TrieId,
/// The size of stored value in octet.
pub storage_size: u64,
pub storage_size: u32,
/// The code associated with a given account.
pub code_hash: CodeHash,
pub rent_allowance: Balance,
@@ -199,7 +198,7 @@ pub struct RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
pub struct TombstoneContractInfo<T: Trait>(T::Hash);
impl<T: Trait> TombstoneContractInfo<T> {
fn new(storage_root: Vec<u8>, storage_size: u64, code_hash: CodeHash<T>) -> Self {
fn new(storage_root: Vec<u8>, storage_size: u32, code_hash: CodeHash<T>) -> Self {
let mut buf = Vec::new();
storage_root.using_encoded(|encoded| buf.extend_from_slice(encoded));
storage_size.using_encoded(|encoded| buf.extend_from_slice(encoded));
@@ -252,7 +251,8 @@ where
}
pub type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
pub type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
pub type NegativeImbalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
pub trait Trait: timestamp::Trait {
type Currency: Currency<Self::AccountId>;
@@ -263,8 +263,8 @@ pub trait Trait: timestamp::Trait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
// `As<u32>` is needed for wasm-utils
type Gas: Parameter + Default + Codec + SimpleArithmetic + Bounded + Copy + As<BalanceOf<Self>> + As<u64> + As<u32>;
type Gas: Parameter + Default + Codec + SimpleArithmetic + Bounded + Copy +
Into<BalanceOf<Self>> + TryFrom<BalanceOf<Self>>;
/// A function type to get the contract address given the creator.
type DetermineContractAddress: ContractAddressFor<CodeHash<Self>, Self::AccountId>;
@@ -310,10 +310,10 @@ where
pub struct DefaultDispatchFeeComputor<T: Trait>(PhantomData<T>);
impl<T: Trait> ComputeDispatchFee<T::Call, BalanceOf<T>> for DefaultDispatchFeeComputor<T> {
fn compute_dispatch_fee(call: &T::Call) -> BalanceOf<T> {
let encoded_len = call.using_encoded(|encoded| encoded.len());
let encoded_len = call.using_encoded(|encoded| encoded.len() as u32);
let base_fee = <Module<T>>::transaction_base_fee();
let byte_fee = <Module<T>>::transaction_byte_fee();
base_fee + byte_fee * <BalanceOf<T> as As<u64>>::sa(encoded_len as u64)
base_fee + byte_fee * encoded_len.into()
}
}
@@ -553,7 +553,7 @@ decl_storage! {
TombstoneDeposit get(tombstone_deposit) config(): BalanceOf<T>;
/// Size of a contract at the time of creation. This is a simple way to ensure
/// that empty contracts eventually gets deleted.
StorageSizeOffset get(storage_size_offset) config(): u64;
StorageSizeOffset get(storage_size_offset) config(): u32;
/// Price of a byte of storage per one block interval. Should be greater than 0.
RentByteFee get(rent_byte_price) config(): BalanceOf<T>;
/// The amount of funds a contract should deposit in order to offset
@@ -576,17 +576,17 @@ decl_storage! {
/// The fee to be paid for making a transaction; the per-byte portion.
TransactionByteFee get(transaction_byte_fee) config(): BalanceOf<T>;
/// The fee required to create a contract instance.
ContractFee get(contract_fee) config(): BalanceOf<T> = BalanceOf::<T>::sa(21);
ContractFee get(contract_fee) config(): BalanceOf<T> = 21.into();
/// The base fee charged for calling into a contract.
CallBaseFee get(call_base_fee) config(): T::Gas = T::Gas::sa(135);
CallBaseFee get(call_base_fee) config(): T::Gas = 135.into();
/// The base fee charged for creating a contract.
CreateBaseFee get(create_base_fee) config(): T::Gas = T::Gas::sa(175);
CreateBaseFee get(create_base_fee) config(): T::Gas = 175.into();
/// The price of one unit of gas.
GasPrice get(gas_price) config(): BalanceOf<T> = BalanceOf::<T>::sa(1);
GasPrice get(gas_price) config(): BalanceOf<T> = 1.into();
/// The maximum nesting level of a call/create stack.
MaxDepth get(max_depth) config(): u32 = 100;
/// The maximum amount of gas that could be expended per block.
BlockGasLimit get(block_gas_limit) config(): T::Gas = T::Gas::sa(10_000_000);
BlockGasLimit get(block_gas_limit) config(): T::Gas = 10_000_000.into();
/// Gas spent so far in this block.
GasSpent get(gas_spent): T::Gas;
/// Current cost schedule for contracts.
@@ -692,19 +692,19 @@ pub struct Schedule<Gas> {
pub enable_println: bool,
}
impl<Gas: As<u64>> Default for Schedule<Gas> {
impl<Gas: From<u32>> Default for Schedule<Gas> {
fn default() -> Schedule<Gas> {
Schedule {
version: 0,
put_code_per_byte_cost: Gas::sa(1),
grow_mem_cost: Gas::sa(1),
regular_op_cost: Gas::sa(1),
return_data_per_byte_cost: Gas::sa(1),
event_data_per_byte_cost: Gas::sa(1),
event_per_topic_cost: Gas::sa(1),
event_base_cost: Gas::sa(1),
sandbox_data_read_cost: Gas::sa(1),
sandbox_data_write_cost: Gas::sa(1),
put_code_per_byte_cost: 1.into(),
grow_mem_cost: 1.into(),
regular_op_cost: 1.into(),
return_data_per_byte_cost: 1.into(),
event_data_per_byte_cost: 1.into(),
event_per_topic_cost: 1.into(),
event_base_cost: 1.into(),
sandbox_data_read_cost: 1.into(),
sandbox_data_write_cost: 1.into(),
max_event_topics: 4,
max_stack_height: 64 * 1024,
max_memory_pages: 16,
+5 -4
View File
@@ -15,7 +15,8 @@
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use crate::{BalanceOf, ContractInfo, ContractInfoOf, Module, TombstoneContractInfo, Trait};
use runtime_primitives::traits::{As, Bounded, CheckedDiv, CheckedMul, Saturating, Zero};
use runtime_primitives::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero,
SaturatedConversion};
use srml_support::traits::{Currency, ExistenceRequirement, Imbalance, WithdrawReason};
use srml_support::StorageMap;
@@ -75,10 +76,10 @@ fn try_evict_or_and_pay_rent<T: Trait>(
let fee_per_block = {
let free_storage = balance
.checked_div(&<Module<T>>::rent_deposit_offset())
.unwrap_or(<BalanceOf<T>>::sa(0));
.unwrap_or_else(Zero::zero);
let effective_storage_size =
<BalanceOf<T>>::sa(contract.storage_size).saturating_sub(free_storage);
<BalanceOf<T>>::from(contract.storage_size).saturating_sub(free_storage);
effective_storage_size
.checked_mul(&<Module<T>>::rent_byte_price())
@@ -95,7 +96,7 @@ fn try_evict_or_and_pay_rent<T: Trait>(
let subsistence_threshold = T::Currency::minimum_balance() + <Module<T>>::tombstone_deposit();
let dues = fee_per_block
.checked_mul(&<BalanceOf<T>>::sa(blocks_passed.as_()))
.checked_mul(&blocks_passed.saturated_into::<u32>().into())
.unwrap_or(<BalanceOf<T>>::max_value());
let dues_limited = dues.min(contract.rent_allowance);
+9 -9
View File
@@ -21,8 +21,8 @@
use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb};
use crate::{
BalanceOf, ComputeDispatchFee, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, Module,
RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, TrieIdGenerator,
BalanceOf, ComputeDispatchFee, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig,
Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, TrieIdGenerator,
};
use assert_matches::assert_matches;
use hex_literal::*;
@@ -30,7 +30,7 @@ use parity_codec::{Decode, Encode, KeyedVec};
use runtime_io;
use runtime_io::with_externalities;
use runtime_primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, H256};
use runtime_primitives::traits::{As, BlakeTwo256, IdentityLookup};
use runtime_primitives::traits::{BlakeTwo256, IdentityLookup};
use runtime_primitives::BuildStorage;
use srml_support::{
assert_ok, impl_outer_dispatch, impl_outer_event, impl_outer_origin, storage::child,
@@ -689,7 +689,7 @@ fn storage_size() {
Origin::signed(ALICE),
30_000,
100_000, HASH_SET_RENT.into(),
<Test as balances::Trait>::Balance::sa(1_000u64).encode() // rent allowance
<Test as balances::Trait>::Balance::from(1_000u32).encode() // rent allowance
));
let bob_contract = super::ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap();
assert_eq!(bob_contract.storage_size, Contract::storage_size_offset() + 4);
@@ -719,7 +719,7 @@ fn deduct_blocks() {
Origin::signed(ALICE),
30_000,
100_000, HASH_SET_RENT.into(),
<Test as balances::Trait>::Balance::sa(1_000u64).encode() // rent allowance
<Test as balances::Trait>::Balance::from(1_000u32).encode() // rent allowance
));
// Check creation
@@ -812,7 +812,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool)
Origin::signed(ALICE),
100,
100_000, HASH_SET_RENT.into(),
<Test as balances::Trait>::Balance::sa(1_000u64).encode() // rent allowance
<Test as balances::Trait>::Balance::from(1_000u32).encode() // rent allowance
));
// Advance blocks
@@ -848,7 +848,7 @@ fn removals(trigger_call: impl Fn() -> bool) {
Origin::signed(ALICE),
100,
100_000, HASH_SET_RENT.into(),
<Test as balances::Trait>::Balance::sa(1_000u64).encode() // rent allowance
<Test as balances::Trait>::Balance::from(1_000u32).encode() // rent allowance
));
// Trigger rent must have no effect
@@ -882,7 +882,7 @@ fn removals(trigger_call: impl Fn() -> bool) {
Origin::signed(ALICE),
1_000,
100_000, HASH_SET_RENT.into(),
<Test as balances::Trait>::Balance::sa(100u64).encode() // rent allowance
<Test as balances::Trait>::Balance::from(100u32).encode() // rent allowance
));
// Trigger rent must have no effect
@@ -916,7 +916,7 @@ fn removals(trigger_call: impl Fn() -> bool) {
Origin::signed(ALICE),
50+Balances::minimum_balance(),
100_000, HASH_SET_RENT.into(),
<Test as balances::Trait>::Balance::sa(1_000u64).encode() // rent allowance
<Test as balances::Trait>::Balance::from(1_000u32).encode() // rent allowance
));
// Trigger rent must have no effect
@@ -29,7 +29,7 @@ use crate::gas::{GasMeter, Token};
use crate::wasm::{prepare, runtime::Env, PrefabWasmModule};
use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait};
use rstd::prelude::*;
use runtime_primitives::traits::{As, CheckedMul, Hash, Bounded};
use runtime_primitives::traits::{CheckedMul, Hash, Bounded};
use srml_support::StorageMap;
/// Gas metering token that used for charging storing code into the code storage.
@@ -37,16 +37,15 @@ use srml_support::StorageMap;
/// Specifies the code length in bytes.
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
#[derive(Copy, Clone)]
pub struct PutCodeToken(u64);
pub struct PutCodeToken(u32);
impl<T: Trait> Token<T> for PutCodeToken {
type Metadata = Schedule<T::Gas>;
fn calculate_amount(&self, metadata: &Schedule<T::Gas>) -> T::Gas {
let code_len_in_gas = <T::Gas as As<u64>>::sa(self.0);
metadata
.put_code_per_byte_cost
.checked_mul(&code_len_in_gas)
.checked_mul(&self.0.into())
.unwrap_or_else(|| Bounded::max_value())
}
}
@@ -63,7 +62,7 @@ pub fn save<T: Trait>(
// The first time instrumentation is on the user. However, consequent reinstrumentation
// due to the schedule changes is on governance system.
if gas_meter
.charge(schedule, PutCodeToken(original_code.len() as u64))
.charge(schedule, PutCodeToken(original_code.len() as u32))
.is_out_of_gas()
{
return Err("there is not enough gas for storing the code");
@@ -195,7 +195,7 @@ macro_rules! define_env {
mod tests {
use parity_wasm::elements::FunctionType;
use parity_wasm::elements::ValueType;
use runtime_primitives::traits::{As, Zero};
use runtime_primitives::traits::Zero;
use sandbox::{self, ReturnValue, TypedValue};
use crate::wasm::tests::MockExt;
use crate::wasm::Runtime;
@@ -256,7 +256,7 @@ mod tests {
#[test]
fn macro_define_func() {
define_func!( <E: Ext> ext_gas (_ctx, amount: u32) => {
let amount = <<E::T as Trait>::Gas as As<u32>>::sa(amount);
let amount = <E::T as Trait>::Gas::from(amount);
if !amount.is_zero() {
Ok(())
} else {
@@ -308,7 +308,7 @@ mod tests {
define_env!(Env, <E: Ext>,
ext_gas( _ctx, amount: u32 ) => {
let amount = <<E::T as Trait>::Gas as As<u32>>::sa(amount);
let amount = <E::T as Trait>::Gas::from(amount);
if !amount.is_zero() {
Ok(())
} else {
+4 -4
View File
@@ -26,7 +26,7 @@ use parity_wasm::elements::{self, Internal, External, MemoryType, Type};
use pwasm_utils;
use pwasm_utils::rules;
use rstd::prelude::*;
use runtime_primitives::traits::As;
use runtime_primitives::traits::{UniqueSaturatedInto, SaturatedConversion};
struct ContractModule<'a, Gas: 'a> {
/// A deserialized module. The module is valid (this is Guaranteed by `new` method).
@@ -38,7 +38,7 @@ struct ContractModule<'a, Gas: 'a> {
schedule: &'a Schedule<Gas>,
}
impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
impl<'a, Gas: 'a + From<u32> + UniqueSaturatedInto<u32> + Clone> ContractModule<'a, Gas> {
/// Creates a new instance of `ContractModule`.
///
/// Returns `Err` if the `original_code` couldn't be decoded or
@@ -85,10 +85,10 @@ impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
fn inject_gas_metering(&mut self) -> Result<(), &'static str> {
let gas_rules =
rules::Set::new(
self.schedule.regular_op_cost.clone().as_(),
self.schedule.regular_op_cost.clone().saturated_into(),
Default::default(),
)
.with_grow_cost(self.schedule.grow_mem_cost.clone().as_())
.with_grow_cost(self.schedule.grow_mem_cost.clone().saturated_into())
.with_forbidden_floats();
let module = self
+10 -11
View File
@@ -27,7 +27,7 @@ use system;
use rstd::prelude::*;
use rstd::mem;
use parity_codec::{Decode, Encode};
use runtime_primitives::traits::{As, CheckedMul, CheckedAdd, Bounded};
use runtime_primitives::traits::{CheckedMul, CheckedAdd, Bounded, SaturatedConversion};
/// Enumerates all possible *special* trap conditions.
///
@@ -122,24 +122,24 @@ impl<T: Trait> Token<T> for RuntimeToken<T::Gas> {
fn calculate_amount(&self, metadata: &Schedule<T::Gas>) -> T::Gas {
use self::RuntimeToken::*;
let value = match *self {
Explicit(amount) => Some(<T::Gas as As<u32>>::sa(amount)),
Explicit(amount) => Some(amount.into()),
ReadMemory(byte_count) => metadata
.sandbox_data_read_cost
.checked_mul(&<T::Gas as As<u32>>::sa(byte_count)),
.checked_mul(&byte_count.into()),
WriteMemory(byte_count) => metadata
.sandbox_data_write_cost
.checked_mul(&<T::Gas as As<u32>>::sa(byte_count)),
.checked_mul(&byte_count.into()),
ReturnData(byte_count) => metadata
.return_data_per_byte_cost
.checked_mul(&<T::Gas as As<u32>>::sa(byte_count)),
.checked_mul(&byte_count.into()),
DepositEvent(topic_count, data_byte_count) => {
let data_cost = metadata
.event_data_per_byte_cost
.checked_mul(&<T::Gas as As<u32>>::sa(data_byte_count));
.checked_mul(&data_byte_count.into());
let topics_cost = metadata
.event_per_topic_cost
.checked_mul(&<T::Gas as As<u32>>::sa(topic_count));
.checked_mul(&topic_count.into());
data_cost
.and_then(|data_cost| {
@@ -340,7 +340,7 @@ define_env!(Env, <E: Ext>,
let nested_gas_limit = if gas == 0 {
ctx.gas_meter.gas_left()
} else {
<<E::T as Trait>::Gas as As<u64>>::sa(gas)
gas.saturated_into()
};
let ext = &mut ctx.ext;
let call_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| {
@@ -413,7 +413,7 @@ define_env!(Env, <E: Ext>,
let nested_gas_limit = if gas == 0 {
ctx.gas_meter.gas_left()
} else {
<<E::T as Trait>::Gas as As<u64>>::sa(gas)
gas.saturated_into()
};
let ext = &mut ctx.ext;
let instantiate_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| {
@@ -535,8 +535,7 @@ define_env!(Env, <E: Ext>,
// Load the latest block timestamp into the scratch buffer
ext_now(ctx) => {
let now: u64 = As::as_(ctx.ext.now().clone());
ctx.scratch_buf = now.encode();
ctx.scratch_buf = ctx.ext.now().encode();
Ok(())
},
+7 -7
View File
@@ -17,7 +17,7 @@
//! Council system: Handles the voting in and maintenance of council members.
use rstd::prelude::*;
use primitives::traits::{Zero, One, As, StaticLookup};
use primitives::traits::{Zero, One, StaticLookup};
use runtime_io::print;
use srml_support::{
StorageValue, StorageMap, dispatch::Result, decl_storage, decl_event, ensure,
@@ -230,7 +230,7 @@ decl_module! {
let (_, _, expiring) = Self::next_finalize().ok_or("cannot present outside of presentation period")?;
let stakes = Self::snapshoted_stakes();
let voters = Self::voters();
let bad_presentation_punishment = Self::present_slash_per_voter() * BalanceOf::<T>::sa(voters.len() as u64);
let bad_presentation_punishment = Self::present_slash_per_voter() * BalanceOf::<T>::from(voters.len() as u32);
ensure!(T::Currency::can_slash(&who, bad_presentation_punishment), "presenter must have sufficient slashable funds");
let mut leaderboard = Self::leaderboard().ok_or("leaderboard must exist while present phase active")?;
@@ -313,22 +313,22 @@ decl_storage! {
// parameters
/// How much should be locked up in order to submit one's candidacy.
pub CandidacyBond get(candidacy_bond) config(): BalanceOf<T> = BalanceOf::<T>::sa(9);
pub CandidacyBond get(candidacy_bond) config(): BalanceOf<T> = 9.into();
/// How much should be locked up in order to be able to submit votes.
pub VotingBond get(voting_bond) config(voter_bond): BalanceOf<T>;
/// The punishment, per voter, if you provide an invalid presentation.
pub PresentSlashPerVoter get(present_slash_per_voter) config(): BalanceOf<T> = BalanceOf::<T>::sa(1);
pub PresentSlashPerVoter get(present_slash_per_voter) config(): BalanceOf<T> = 1.into();
/// How many runners-up should have their approvals persist until the next vote.
pub CarryCount get(carry_count) config(): u32 = 2;
/// How long to give each top candidate to present themselves after the vote ends.
pub PresentationDuration get(presentation_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000);
pub PresentationDuration get(presentation_duration) config(): T::BlockNumber = 1000.into();
/// How many vote indexes need to go by after a target voter's last vote before they can be reaped if their
/// approvals are moot.
pub InactiveGracePeriod get(inactivity_grace_period) config(inactive_grace_period): VoteIndex = 1;
/// How often (in blocks) to check for new votes.
pub VotingPeriod get(voting_period) config(approval_voting_period): T::BlockNumber = T::BlockNumber::sa(1000);
pub VotingPeriod get(voting_period) config(approval_voting_period): T::BlockNumber = 1000.into();
/// How long each position is active for.
pub TermDuration get(term_duration) config(): T::BlockNumber = T::BlockNumber::sa(5);
pub TermDuration get(term_duration) config(): T::BlockNumber = 5.into();
/// Number of accounts that should be sitting on the council.
pub DesiredSeats get(desired_seats) config(): u32;
+4 -4
View File
@@ -18,7 +18,7 @@
use rstd::prelude::*;
use rstd::borrow::Borrow;
use primitives::traits::{Hash, As, Zero};
use primitives::traits::{Hash, Zero};
use runtime_io::print;
use srml_support::dispatch::Result;
use srml_support::{StorageValue, StorageMap, IsSubType, decl_module, decl_storage, decl_event, ensure};
@@ -113,10 +113,10 @@ decl_module! {
decl_storage! {
trait Store for Module<T: Trait> as CouncilVoting {
pub CooloffPeriod get(cooloff_period) config(): T::BlockNumber = T::BlockNumber::sa(1000);
pub VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(3);
pub CooloffPeriod get(cooloff_period) config(): T::BlockNumber = 1000.into();
pub VotingPeriod get(voting_period) config(): T::BlockNumber = 3.into();
/// Number of blocks by which to delay enactment of successful, non-unanimous-council-instigated referendum proposals.
pub EnactDelayPeriod get(enact_delay_period) config(): T::BlockNumber = T::BlockNumber::sa(0);
pub EnactDelayPeriod get(enact_delay_period) config(): T::BlockNumber = 0.into();
pub Proposals get(proposals) build(|_| vec![]): Vec<(T::BlockNumber, T::Hash)>; // ordered by expiry.
pub ProposalOf get(proposal_of): map T::Hash => Option<T::Proposal>;
pub ProposalVoters get(proposal_voters): map T::Hash => Vec<T::AccountId>;
+9 -9
View File
@@ -20,7 +20,7 @@
use rstd::prelude::*;
use rstd::result;
use primitives::traits::{Zero, As, Bounded};
use primitives::traits::{Zero, Bounded};
use parity_codec::{Encode, Decode};
use srml_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType, EnumerableStorageMap};
use srml_support::{decl_module, decl_storage, decl_event, ensure};
@@ -196,7 +196,7 @@ decl_module! {
// Indefinite lock is reduced to the maximum voting lock that could be possible.
let lock_period = Self::public_delay();
let now = <system::Module<T>>::block_number();
let locked_until = now + lock_period * T::BlockNumber::sa(d.1 as u64);
let locked_until = now + lock_period * (d.1 as u32).into();
T::Currency::set_lock(DEMOCRACY_ID, &who, Bounded::max_value(), locked_until, WithdrawReason::Transfer.into());
Self::deposit_event(RawEvent::Undelegated(who));
}
@@ -234,7 +234,7 @@ decl_storage! {
/// Those who have locked a deposit.
pub DepositOf get(deposit_of): map PropIndex => Option<(BalanceOf<T>, Vec<T::AccountId>)>;
/// How often (in blocks) new public referenda are launched.
pub LaunchPeriod get(launch_period) config(): T::BlockNumber = T::BlockNumber::sa(1000);
pub LaunchPeriod get(launch_period) config(): T::BlockNumber = 1000.into();
/// The minimum amount to be used as a deposit for a public referendum proposal.
pub MinimumDeposit get(minimum_deposit) config(): BalanceOf<T>;
/// The delay before enactment for all public referenda.
@@ -243,7 +243,7 @@ decl_storage! {
pub MaxLockPeriods get(max_lock_periods) config(): LockPeriods;
/// How often (in blocks) to check for new votes.
pub VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(1000);
pub VotingPeriod get(voting_period) config(): T::BlockNumber = 1000.into();
/// The next free referendum index, aka the number of referenda started so far.
pub ReferendumCount get(referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex;
@@ -290,7 +290,7 @@ impl<T: Trait> Module<T> {
/// Get the amount locked in support of `proposal`; `None` if proposal isn't a valid proposal
/// index.
pub fn locked_for(proposal: PropIndex) -> Option<BalanceOf<T>> {
Self::deposit_of(proposal).map(|(d, l)| d * BalanceOf::<T>::sa(l.len() as u64))
Self::deposit_of(proposal).map(|(d, l)| d * (l.len() as u32).into())
}
/// Return true if `ref_index` is an on-going referendum.
@@ -325,9 +325,9 @@ impl<T: Trait> Module<T> {
))
.map(|(bal, vote)|
if vote.is_aye() {
(bal * BalanceOf::<T>::sa(vote.multiplier() as u64), Zero::zero(), bal)
(bal * (vote.multiplier() as u32).into(), Zero::zero(), bal)
} else {
(Zero::zero(), bal * BalanceOf::<T>::sa(vote.multiplier() as u64), bal)
(Zero::zero(), bal * (vote.multiplier() as u32).into(), bal)
}
).fold((Zero::zero(), Zero::zero(), Zero::zero()), |(a, b, c), (d, e, f)| (a + d, b + e, c + f));
let (del_approve, del_against, del_capital) = Self::tally_delegation(ref_index);
@@ -361,7 +361,7 @@ impl<T: Trait> Module<T> {
.fold((Zero::zero(), Zero::zero()), |(votes_acc, balance_acc), (delegator, (_delegate, periods))| {
let lock_periods = if min_lock_periods <= periods { min_lock_periods } else { periods };
let balance = T::Currency::total_balance(&delegator);
let votes = T::Currency::total_balance(&delegator) * BalanceOf::<T>::sa(lock_periods as u64);
let votes = T::Currency::total_balance(&delegator) * (lock_periods as u32).into();
let (del_votes, del_balance) = Self::delegated_votes(ref_index, delegator, lock_periods, recursion_limit - 1);
(votes_acc + votes + del_votes, balance_acc + balance + del_balance)
})
@@ -469,7 +469,7 @@ impl<T: Trait> Module<T> {
{
// now plus: the base lock period multiplied by the number of periods this voter offered to
// lock should they win...
let locked_until = now + lock_period * T::BlockNumber::sa((vote.multiplier()) as u64);
let locked_until = now + lock_period * (vote.multiplier() as u32).into();
// ...extend their bondage until at least then.
T::Currency::extend_lock(DEMOCRACY_ID, &a, Bounded::max_value(), locked_until, WithdrawReason::Transfer.into());
}
+8 -8
View File
@@ -26,7 +26,7 @@ use inherents::{
InherentData, MakeFatalError,
};
use srml_support::StorageValue;
use primitives::traits::{As, One, Zero};
use primitives::traits::{One, Zero, SaturatedConversion};
use rstd::{prelude::*, result, cmp, vec};
use parity_codec::Decode;
use srml_system::{ensure_none, Trait as SystemTrait};
@@ -34,8 +34,8 @@ use srml_system::{ensure_none, Trait as SystemTrait};
#[cfg(feature = "std")]
use parity_codec::Encode;
const DEFAULT_WINDOW_SIZE: u64 = 101;
const DEFAULT_DELAY: u64 = 1000;
const DEFAULT_WINDOW_SIZE: u32 = 101;
const DEFAULT_DELAY: u32 = 1000;
/// The identifier for the `finalnum` inherent.
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"finalnum";
@@ -100,9 +100,9 @@ decl_storage! {
/// The median.
Median get(median) build(|_| T::BlockNumber::zero()): T::BlockNumber;
/// The number of recent samples to keep from this chain. Default is n-100
pub WindowSize get(window_size) config(window_size): T::BlockNumber = T::BlockNumber::sa(DEFAULT_WINDOW_SIZE);
pub WindowSize get(window_size) config(window_size): T::BlockNumber = DEFAULT_WINDOW_SIZE.into();
/// The delay after which point things become suspicious.
pub ReportLatency get(report_latency) config(report_latency): T::BlockNumber = T::BlockNumber::sa(DEFAULT_DELAY);
pub ReportLatency get(report_latency) config(report_latency): T::BlockNumber = DEFAULT_DELAY.into();
/// Final hint to apply in the block. `None` means "same as parent".
Update: Option<T::BlockNumber>;
@@ -154,7 +154,7 @@ impl<T: Trait> Module<T> {
// the sample size has just been shrunk.
{
// take into account the item we haven't pushed yet.
let to_prune = (recent.len() + 1).saturating_sub(window_size.as_() as usize);
let to_prune = (recent.len() + 1).saturating_sub(window_size.saturated_into::<usize>());
for drained in recent.drain(..to_prune) {
let idx = ordered.binary_search(&drained)
@@ -188,13 +188,13 @@ impl<T: Trait> Module<T> {
}
};
let our_window_size = recent.len();
let our_window_size = recent.len() as u32;
<Self as Store>::RecentHints::put(recent);
<Self as Store>::OrderedHints::put(ordered);
<Self as Store>::Median::put(median);
if T::BlockNumber::sa(our_window_size as u64) == window_size {
if T::BlockNumber::from(our_window_size) == window_size {
let now = srml_system::Module::<T>::block_number();
let latency = Self::report_latency();
+1 -3
View File
@@ -275,8 +275,6 @@ impl<T: Trait> Module<T> {
in_blocks: T::BlockNumber,
forced: Option<T::BlockNumber>,
) -> Result {
use primitives::traits::As;
if Self::pending_change().is_none() {
let scheduled_at = system::ChainContext::<T>::default().current_height();
@@ -287,7 +285,7 @@ impl<T: Trait> Module<T> {
// only allow the next forced change when twice the window has passed since
// this one.
<NextForced<T>>::put(scheduled_at + in_blocks * T::BlockNumber::sa(2));
<NextForced<T>>::put(scheduled_at + in_blocks * 2.into());
}
<PendingChange<T>>::put(StoredPendingChange {
+34 -20
View File
@@ -18,7 +18,8 @@
#[cfg(feature = "std")]
use std::fmt;
use crate::{Member, Decode, Encode, As, Input, Output};
use rstd::convert::TryInto;
use crate::{Member, Decode, Encode, Input, Output};
/// An indices-aware address, which can be either a direct `AccountId` or
/// an index.
@@ -59,14 +60,20 @@ fn need_more_than<T: PartialOrd>(a: T, b: T) -> Option<T> {
impl<AccountId, AccountIndex> Decode for Address<AccountId, AccountIndex> where
AccountId: Member + Decode,
AccountIndex: Member + Decode + PartialOrd<AccountIndex> + Ord + As<u32> + As<u16> + As<u8> + Copy,
AccountIndex: Member + Decode + PartialOrd<AccountIndex> + Ord + From<u32> + Copy,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(match input.read_byte()? {
x @ 0x00...0xef => Address::Index(As::sa(x)),
0xfc => Address::Index(As::sa(need_more_than(0xef, u16::decode(input)?)?)),
0xfd => Address::Index(As::sa(need_more_than(0xffff, u32::decode(input)?)?)),
0xfe => Address::Index(need_more_than(As::sa(0xffffffffu32), Decode::decode(input)?)?),
x @ 0x00...0xef => Address::Index(AccountIndex::from(x as u32)),
0xfc => Address::Index(AccountIndex::from(
need_more_than(0xef, u16::decode(input)?)? as u32
)),
0xfd => Address::Index(AccountIndex::from(
need_more_than(0xffff, u32::decode(input)?)?
)),
0xfe => Address::Index(
need_more_than(0xffffffffu32.into(), Decode::decode(input)?)?
),
0xff => Address::Id(Decode::decode(input)?),
_ => return None,
})
@@ -75,7 +82,7 @@ impl<AccountId, AccountIndex> Decode for Address<AccountId, AccountIndex> where
impl<AccountId, AccountIndex> Encode for Address<AccountId, AccountIndex> where
AccountId: Member + Encode,
AccountIndex: Member + Encode + PartialOrd<AccountIndex> + Ord + As<u32> + As<u16> + As<u8> + Copy,
AccountIndex: Member + Encode + PartialOrd<AccountIndex> + Ord + Copy + From<u32> + TryInto<u32>,
{
fn encode_to<T: Output>(&self, dest: &mut T) {
match *self {
@@ -83,19 +90,26 @@ impl<AccountId, AccountIndex> Encode for Address<AccountId, AccountIndex> where
dest.push_byte(255);
dest.push(i);
}
Address::Index(i) if i > As::sa(0xffffffffu32) => {
dest.push_byte(254);
dest.push(&i);
}
Address::Index(i) if i > As::sa(0xffffu32) => {
dest.push_byte(253);
dest.push(&As::<u32>::as_(i));
}
Address::Index(i) if i >= As::sa(0xf0u32) => {
dest.push_byte(252);
dest.push(&As::<u16>::as_(i));
}
Address::Index(i) => dest.push_byte(As::<u8>::as_(i)),
Address::Index(i) => {
let maybe_u32: Result<u32, _> = i.try_into();
if let Ok(x) = maybe_u32 {
if x > 0xffff {
dest.push_byte(253);
dest.push(&x);
}
else if x >= 0xf0 {
dest.push_byte(252);
dest.push(&(x as u16));
}
else {
dest.push_byte(x as u8);
}
} else {
dest.push_byte(254);
dest.push(&i);
}
},
}
}
}
+40 -27
View File
@@ -19,10 +19,10 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::{prelude::*, result, marker::PhantomData};
use rstd::{prelude::*, result, marker::PhantomData, convert::TryInto};
use parity_codec::{Encode, Decode, Codec, Input, Output};
use srml_support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage};
use primitives::traits::{One, SimpleArithmetic, As, StaticLookup, Member};
use primitives::traits::{One, SimpleArithmetic, StaticLookup, Member};
use system::{IsDeadAccount, OnNewAccount};
use self::address::Address as RawAddress;
@@ -33,13 +33,13 @@ pub mod address;
mod tests;
/// Number of account IDs stored per enum set.
const ENUM_SET_SIZE: usize = 64;
const ENUM_SET_SIZE: u32 = 64;
pub type Address<T> = RawAddress<<T as system::Trait>::AccountId, <T as Trait>::AccountIndex>;
/// Turn an Id into an Index, or None for the purpose of getting
/// a hint at a possibly desired index.
pub trait ResolveHint<AccountId: Encode, AccountIndex: As<usize>> {
pub trait ResolveHint<AccountId, AccountIndex> {
/// Turn an Id into an Index, or None for the purpose of getting
/// a hint at a possibly desired index.
fn resolve_hint(who: &AccountId) -> Option<AccountIndex>;
@@ -47,9 +47,11 @@ pub trait ResolveHint<AccountId: Encode, AccountIndex: As<usize>> {
/// Simple encode-based resolve hint implemenntation.
pub struct SimpleResolveHint<AccountId, AccountIndex>(PhantomData<(AccountId, AccountIndex)>);
impl<AccountId: Encode, AccountIndex: As<usize>> ResolveHint<AccountId, AccountIndex> for SimpleResolveHint<AccountId, AccountIndex> {
impl<AccountId: Encode, AccountIndex: From<u32>>
ResolveHint<AccountId, AccountIndex> for SimpleResolveHint<AccountId, AccountIndex>
{
fn resolve_hint(who: &AccountId) -> Option<AccountIndex> {
Some(AccountIndex::sa(who.using_encoded(|e| e[0] as usize + e[1] as usize * 256)))
Some(AccountIndex::from(who.using_encoded(|e| e[0] as u32 + e[1] as u32 * 256)))
}
}
@@ -57,7 +59,7 @@ impl<AccountId: Encode, AccountIndex: As<usize>> ResolveHint<AccountId, AccountI
pub trait Trait: system::Trait {
/// Type used for storing an account's index; implies the maximum number of accounts the system
/// can hold.
type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + As<u8> + As<u16> + As<u32> + As<u64> + As<usize> + Copy;
type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + Copy;
/// Whether an account is dead or not.
type IsDeadAccount: IsDeadAccount<Self::AccountId>;
@@ -92,15 +94,18 @@ decl_storage! {
trait Store for Module<T: Trait> as Indices {
/// The next free enumeration set.
pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig<T>| {
T::AccountIndex::sa(config.ids.len() / ENUM_SET_SIZE)
(config.ids.len() as u32 / ENUM_SET_SIZE).into()
}): T::AccountIndex;
/// The enumeration sets.
pub EnumSet get(enum_set) build(|config: &GenesisConfig<T>| {
(0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE)
(0..((config.ids.len() as u32) + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE)
.map(|i| (
T::AccountIndex::sa(i),
config.ids[i * ENUM_SET_SIZE..config.ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned(),
i.into(),
config.ids[
(i * ENUM_SET_SIZE) as usize..
config.ids.len().min(((i + 1) * ENUM_SET_SIZE) as usize)
].to_owned(),
))
.collect::<Vec<_>>()
}): map T::AccountIndex => Vec<T::AccountId>;
@@ -117,7 +122,7 @@ impl<T: Trait> Module<T> {
pub fn lookup_index(index: T::AccountIndex) -> Option<T::AccountId> {
let enum_set_size = Self::enum_set_size();
let set = Self::enum_set(index / enum_set_size);
let i: usize = (index % enum_set_size).as_();
let i: usize = (index % enum_set_size).try_into().ok()?;
set.get(i).cloned()
}
@@ -125,12 +130,18 @@ impl<T: Trait> Module<T> {
pub fn can_reclaim(try_index: T::AccountIndex) -> bool {
let enum_set_size = Self::enum_set_size();
let try_set = Self::enum_set(try_index / enum_set_size);
let i = (try_index % enum_set_size).as_();
i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i])
let maybe_usize: Result<usize, _> = (try_index % enum_set_size).try_into();
if let Ok(i) = maybe_usize {
i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i])
} else {
false
}
}
/// Lookup an address to get an Id, if there's one there.
pub fn lookup_address(a: address::Address<T::AccountId, T::AccountIndex>) -> Option<T::AccountId> {
pub fn lookup_address(
a: address::Address<T::AccountId, T::AccountIndex>
) -> Option<T::AccountId> {
match a {
address::Address::Id(i) => Some(i),
address::Address::Index(i) => Self::lookup_index(i),
@@ -140,7 +151,7 @@ impl<T: Trait> Module<T> {
// PUBLIC MUTABLES (DANGEROUS)
fn enum_set_size() -> T::AccountIndex {
T::AccountIndex::sa(ENUM_SET_SIZE)
ENUM_SET_SIZE.into()
}
}
@@ -153,36 +164,38 @@ impl<T: Trait> OnNewAccount<T::AccountId> for Module<T> {
// then check to see if this account id identifies a dead account index.
let set_index = try_index / enum_set_size;
let mut try_set = Self::enum_set(set_index);
let item_index = (try_index % enum_set_size).as_();
if item_index < try_set.len() {
if T::IsDeadAccount::is_dead_account(&try_set[item_index]) {
// yup - this index refers to a dead account. can be reused.
try_set[item_index] = who.clone();
<EnumSet<T>>::insert(set_index, try_set);
if let Ok(item_index) = (try_index % enum_set_size).try_into() {
if item_index < try_set.len() {
if T::IsDeadAccount::is_dead_account(&try_set[item_index]) {
// yup - this index refers to a dead account. can be reused.
try_set[item_index] = who.clone();
<EnumSet<T>>::insert(set_index, try_set);
return
return
}
}
}
}
// insert normally as a back up
let mut set_index = next_set_index;
// defensive only: this loop should never iterate since we keep NextEnumSet up to date later.
// defensive only: this loop should never iterate since we keep NextEnumSet up to date
// later.
let mut set = loop {
let set = Self::enum_set(set_index);
if set.len() < ENUM_SET_SIZE {
if set.len() < ENUM_SET_SIZE as usize {
break set;
}
set_index += One::one();
};
let index = T::AccountIndex::sa(set_index.as_() * ENUM_SET_SIZE + set.len());
let index = set_index * enum_set_size + T::AccountIndex::from(set.len() as u32);
// update set.
set.push(who.clone());
// keep NextEnumSet up to date
if set.len() == ENUM_SET_SIZE {
if set.len() == ENUM_SET_SIZE as usize {
<NextEnumSet<T>>::put(set_index + One::one());
}
+3 -3
View File
@@ -116,7 +116,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::prelude::*;
use primitives::traits::{As, Zero, One, Convert};
use primitives::traits::{Zero, One, Convert};
use srml_support::{StorageValue, StorageMap, for_each_tuple, decl_module, decl_event, decl_storage};
use srml_support::{dispatch::Result, traits::OnFreeBalanceZero};
use system::ensure_signed;
@@ -200,9 +200,9 @@ decl_storage! {
/// The current set of validators.
pub Validators get(validators) config(): Vec<T::AccountId>;
/// Current length of the session.
pub SessionLength get(length) config(session_length): T::BlockNumber = T::BlockNumber::sa(1000);
pub SessionLength get(length) config(session_length): T::BlockNumber = 1000.into();
/// Current index of the session.
pub CurrentIndex get(current_index) build(|_| T::BlockNumber::sa(0)): T::BlockNumber;
pub CurrentIndex get(current_index) build(|_| 0.into()): T::BlockNumber;
/// Timestamp when current session started.
pub CurrentStart get(current_start) build(|_| T::Moment::zero()): T::Moment;
+15 -8
View File
@@ -247,7 +247,10 @@ use srml_support::traits::{
};
use session::OnSessionChange;
use primitives::Perbill;
use primitives::traits::{Convert, Zero, One, As, StaticLookup, CheckedSub, CheckedShl, Saturating, Bounded};
use primitives::traits::{
Convert, Zero, One, StaticLookup, CheckedSub, CheckedShl, Saturating,
Bounded, SaturatedConversion
};
#[cfg(feature = "std")]
use primitives::{Serialize, Deserialize};
use system::ensure_signed;
@@ -396,7 +399,7 @@ type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::
type RawAssignment<T> = (<T as system::Trait>::AccountId, ExtendedBalance);
type Assignment<T> = (<T as system::Trait>::AccountId, ExtendedBalance, BalanceOf<T>);
type ExpoMap<T> = BTreeMap::<<T as system::Trait>::AccountId, Exposure<<T as system::Trait>::AccountId, BalanceOf<T>>>;
type ExpoMap<T> = BTreeMap<<T as system::Trait>::AccountId, Exposure<<T as system::Trait>::AccountId, BalanceOf<T>>>;
pub trait Trait: system::Trait + session::Trait {
/// The staking balance.
@@ -432,7 +435,7 @@ decl_storage! {
/// Minimum number of staking participants before emergency conditions are imposed.
pub MinimumValidatorCount get(minimum_validator_count) config(): u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT;
/// The length of a staking era in sessions.
pub SessionsPerEra get(sessions_per_era) config(): T::BlockNumber = T::BlockNumber::sa(1000);
pub SessionsPerEra get(sessions_per_era) config(): T::BlockNumber = 1000.into();
/// Maximum reward, per validator, that is provided per acceptable session.
pub SessionReward get(session_reward) config(): Perbill = Perbill::from_parts(60);
/// Slash, per validator that is taken for the first time they are found to be offline.
@@ -440,7 +443,7 @@ decl_storage! {
/// Number of instances of offline reports before slashing begins for validators.
pub OfflineSlashGrace get(offline_slash_grace) config(): u32;
/// The length of the bonding duration in eras.
pub BondingDuration get(bonding_duration) config(): T::BlockNumber = T::BlockNumber::sa(12);
pub BondingDuration get(bonding_duration) config(): T::BlockNumber = 12.into();
/// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're easy to initialize
/// and the performance hit is minimal (we expect no more than four invulnerables) and restricted to testnets.
@@ -867,8 +870,12 @@ impl<T: Trait> Module<T> {
if ideal_elapsed.is_zero() {
return Self::current_session_reward();
}
let per65536: u64 = (T::Moment::sa(65536u64) * ideal_elapsed.clone() / actual_elapsed.max(ideal_elapsed)).as_();
Self::current_session_reward() * <BalanceOf<T>>::sa(per65536) / <BalanceOf<T>>::sa(65536u64)
// Assumes we have 16-bits free at the top of T::Moment. Holds true for moment as seconds
// in a u64 for the forseeable future, but more correct would be to handle overflows
// explicitly.
let per65536 = T::Moment::from(65536) * ideal_elapsed.clone() / actual_elapsed.max(ideal_elapsed);
let per65536: BalanceOf<T> = per65536.saturated_into::<u32>().into();
Self::current_session_reward() * per65536 / 65536.into()
}
/// Session has just changed. We need to determine whether we pay a reward, slash and/or
@@ -901,8 +908,8 @@ impl<T: Trait> Module<T> {
Self::reward_validator(v, reward);
}
Self::deposit_event(RawEvent::Reward(reward));
let len = validators.len() as u64; // validators length can never overflow u64
let len = BalanceOf::<T>::sa(len);
let len = validators.len() as u32; // validators length can never overflow u64
let len: BalanceOf<T> = len.into();
let total_minted = reward * len;
let total_rewarded_stake = Self::slot_stake() * len;
T::OnRewardMinted::on_dilution(total_minted, total_rewarded_stake);
+5 -4
View File
@@ -77,8 +77,8 @@ use rstd::prelude::*;
#[cfg(any(feature = "std", test))]
use rstd::map;
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, One, Bounded, Lookup,
Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As, CurrentHeight, BlockNumberToHash,
MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup
Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, CurrentHeight, BlockNumberToHash,
MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, SaturatedConversion
};
#[cfg(any(feature = "std", test))]
use primitives::traits::Zero;
@@ -311,7 +311,7 @@ decl_storage! {
/// ring buffer with the `i8` prefix being the index into the `Vec` of the oldest hash.
RandomMaterial get(random_material): (i8, Vec<T::Hash>);
/// The current block number being processed. Set by `execute_block`.
Number get(block_number) build(|_| T::BlockNumber::sa(1u64)): T::BlockNumber;
Number get(block_number) build(|_| 1.into()): T::BlockNumber;
/// Hash of the previous block.
ParentHash get(parent_hash) build(|_| hash69()): T::Hash;
/// Extrinsics root of the current block, also part of the block header.
@@ -493,7 +493,8 @@ impl<T: Trait> Module<T> {
let mut digest = <Digest<T>>::take();
let extrinsics_root = <ExtrinsicsRoot<T>>::take();
let storage_root = T::Hashing::storage_root();
let storage_changes_root = T::Hashing::storage_changes_root(parent_hash, number.as_() - 1);
let number_u64 = number.saturated_into::<u64>();
let storage_changes_root = T::Hashing::storage_changes_root(parent_hash, number_u64 - 1);
// we can't compute changes trie root earlier && put it to the Digest
// because it will include all currently existing temporaries.
+12 -10
View File
@@ -87,6 +87,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::{result, ops::{Mul, Div}, cmp};
use parity_codec::Encode;
#[cfg(feature = "std")]
use parity_codec::Decode;
@@ -94,9 +95,8 @@ use parity_codec::Decode;
use inherents::ProvideInherentData;
use srml_support::{StorageValue, Parameter, decl_storage, decl_module};
use srml_support::for_each_tuple;
use runtime_primitives::traits::{As, SimpleArithmetic, Zero};
use runtime_primitives::traits::{SimpleArithmetic, Zero, SaturatedConversion};
use system::ensure_none;
use rstd::{result, ops::{Mul, Div}, cmp};
use inherents::{RuntimeString, InherentIdentifier, ProvideInherent, IsFatalError, InherentData};
/// The identifier for the `timestamp` inherent.
@@ -252,7 +252,7 @@ decl_module! {
decl_storage! {
trait Store for Module<T: Trait> as Timestamp {
/// Current time for the current block.
pub Now get(now) build(|_| T::Moment::sa(0)): T::Moment;
pub Now get(now) build(|_| 0.into()): T::Moment;
/// Old storage item provided for compatibility. Remove after all networks upgraded.
// TODO: #2133
@@ -262,7 +262,7 @@ decl_storage! {
/// that the block production apparatus provides. Your chosen consensus system will generally
/// work with this to determine a sensible block time. e.g. For Aura, it will be double this
/// period on default settings.
pub MinimumPeriod get(minimum_period) config(): T::Moment = T::Moment::sa(3);
pub MinimumPeriod get(minimum_period) config(): T::Moment = 3.into();
/// Did the timestamp get updated in this block?
DidUpdate: bool;
@@ -297,23 +297,25 @@ impl<T: Trait> ProvideInherent for Module<T> {
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let data = extract_inherent_data(data).expect("Gets and decodes timestamp inherent data");
let data: T::Moment = extract_inherent_data(data)
.expect("Gets and decodes timestamp inherent data")
.saturated_into();
let next_time = cmp::max(As::sa(data), Self::now() + <MinimumPeriod<T>>::get());
let next_time = cmp::max(data, Self::now() + <MinimumPeriod<T>>::get());
Some(Call::set(next_time.into()))
}
fn check_inherent(call: &Self::Call, data: &InherentData) -> result::Result<(), Self::Error> {
const MAX_TIMESTAMP_DRIFT: u64 = 60;
let t = match call {
Call::set(ref t) => t.clone(),
let t: u64 = match call {
Call::set(ref t) => t.clone().saturated_into::<u64>(),
_ => return Ok(()),
}.as_();
};
let data = extract_inherent_data(data).map_err(|e| InherentError::Other(e))?;
let minimum = (Self::now() + <MinimumPeriod<T>>::get()).as_();
let minimum = (Self::now() + <MinimumPeriod<T>>::get()).saturated_into::<u64>();
if t > data + MAX_TIMESTAMP_DRIFT {
Err(InherentError::Other("Timestamp too far in future to accept".into()))
} else if t < minimum {