diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index e0c683f24c..9944db924b 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -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", diff --git a/substrate/core/cli/src/informant.rs b/substrate/core/cli/src/informant.rs index 0d100c1963..dd0237b7f8 100644 --- a/substrate/core/cli/src/informant.rs +++ b/substrate/core/cli/src/informant.rs @@ -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(service: &Service, exit: ::exit_future::Exit, handle: TaskExecutor) where @@ -47,7 +47,7 @@ pub fn start(service: &Service, 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::(); 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(service: &Service, 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::(); let bandwidth_download = network.average_download_per_sec(); let bandwidth_upload = network.average_upload_per_sec(); info!( diff --git a/substrate/core/cli/src/lib.rs b/substrate/core/cli/src/lib.rs index 3fd3454e0e..3aa567de66 100644 --- a/substrate/core/cli/src/lib.rs +++ b/substrate/core/cli/src/lib.rs @@ -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::( - 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::(spec_factory, &cli.shared_params, version)?; let blocks = cli.num; - Ok(service::chain_ops::revert_chain::(config, As::sa(blocks))?) + Ok(service::chain_ops::revert_chain::(config, blocks.into())?) } fn purge_chain( diff --git a/substrate/core/cli/src/params.rs b/substrate/core/cli/src/params.rs index 503d8fca32..ab473a304b 100644 --- a/substrate/core/cli/src/params.rs +++ b/substrate/core/cli/src/params.rs @@ -533,11 +533,11 @@ pub struct ExportBlocksCmd { /// Specify starting block number. 1 by default. #[structopt(long = "from", value_name = "BLOCK")] - pub from: Option, + pub from: Option, /// Specify last block number. Best block by default. #[structopt(long = "to", value_name = "BLOCK")] - pub to: Option, + pub to: Option, /// 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)] diff --git a/substrate/core/client/db/src/cache/list_cache.rs b/substrate/core/client/db/src/cache/list_cache.rs index 4d7b4e2e51..3c74ac2d1f 100644 --- a/substrate/core/client/db/src/cache/list_cache.rs +++ b/substrate/core/client/db/src/cache/list_cache.rs @@ -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> ListCache // 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> ListCache ) { 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(()), diff --git a/substrate/core/client/db/src/cache/mod.rs b/substrate/core/client/db/src/cache/mod.rs index e4e23a5ca1..d8ffaea723 100644 --- a/substrate/core/client/db/src/cache/mod.rs +++ b/substrate/core/client/db/src/cache/mod.rs @@ -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(), ) }) diff --git a/substrate/core/client/db/src/lib.rs b/substrate/core/client/db/src/lib.rs index a7d7935278..0e65e17f8d 100644 --- a/substrate/core/client/db/src/lib.rs +++ b/substrate/core/client/db/src/lib.rs @@ -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 DbChangesTrieStorage { min_blocks_to_keep, &state_machine::ChangesTrieAnchorBlockId { hash: convert_hash(&block_hash), - number: block_num.as_(), + number: block_num.saturated_into::(), }, |node| tx.delete(columns::CHANGES_TRIE, node.as_ref())); } @@ -477,19 +480,19 @@ impl state_machine::ChangesTrieRootsStorage 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::() { // 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::( - &*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> Backend { ) -> Result<(), client::error::Error> { - let number_u64 = number.as_(); + let number_u64 = number.saturated_into::(); if number_u64 > self.canonicalization_delay { let new_canonical = number_u64 - self.canonicalization_delay; @@ -781,7 +784,7 @@ impl> Backend { 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> Backend { changeset.deleted.push(key); } } - let number_u64 = number.as_(); + let number_u64 = number.saturated_into::(); let commit = self.storage.state_db.insert_block(&hash, number_u64, &pending_block.header.parent_hash(), changeset) .map_err(|e: state_db::Error| client::error::Error::from(format!("State database error: {:?}", e)))?; apply_state_commit(&mut transaction, commit); @@ -978,7 +981,7 @@ impl> Backend { { 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::() > 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 client::backend::Backend for Backend 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::() { + if best.is_zero() { + return Ok(c.saturated_into::>()) } let mut transaction = DBTransaction::new(); match self.storage.state_db.revert_one() { @@ -1138,7 +1141,7 @@ impl client::backend::Backend for Backend 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 client::backend::Backend for Backend 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::>()) } } Ok(n) @@ -1182,7 +1185,7 @@ impl client::backend::Backend for Backend 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::()) { 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 client::backend::Backend for Backend whe } fn have_state_at(&self, hash: &Block::Hash, number: NumberFor) -> bool { - !self.storage.state_db.is_pruned(hash, number.as_()) + !self.storage.state_db.is_pruned(hash, number.saturated_into::()) } fn destroy_state(&self, mut state: Self::State) -> Result<(), client::error::Error> { diff --git a/substrate/core/client/db/src/light.rs b/substrate/core/client/db/src/light.rs index 39817140c6..02525455ba 100644 --- a/substrate/core/client/db/src/light.rs +++ b/substrate/core/client/db/src/light.rs @@ -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 LightStorage { let new_cht_start: NumberFor = cht::start_number(cht::SIZE, new_cht_number); let new_header_cht_root = cht::compute_root::( - 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::()..) + .map(|num| self.hash(num.saturated_into())) )?; transaction.put( columns::CHT, @@ -283,8 +285,8 @@ impl LightStorage { // 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::( - 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::()..) + .map(|num| self.changes_trie_root(BlockId::Number(num.saturated_into()))) )?; transaction.put( columns::CHT, @@ -530,7 +532,7 @@ impl LightBlockchainStorage for LightStorage } /// Build the key for inserting header-CHT at given block. -fn cht_key>(cht_type: u8, block: N) -> [u8; 5] { +fn cht_key>(cht_type: u8, block: N) -> [u8; 5] { let mut key = [cht_type; 5]; key[1..].copy_from_slice(&utils::number_index_key(block)); key diff --git a/substrate/core/client/db/src/utils.rs b/substrate/core/client/db/src/utils.rs index b51faae6de..eec476f40e 100644 --- a/substrate/core/client/db/src/utils.rs +++ b/substrate/core/client/db/src/utils.rs @@ -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) -> NumberIndexKey where N: As { - let n: u64 = n.as_(); - assert!(n & 0xffffffff00000000 == 0); - +pub fn number_index_key>(n: N) -> NumberIndexKey { + let n = n.checked_into::().unwrap(); [ (n >> 24) as u8, ((n >> 16) & 0xff) as u8, @@ -93,7 +95,7 @@ pub fn number_index_key(n: N) -> NumberIndexKey where N: As { /// 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(number: N, hash: H) -> Vec where - N: As, + N: TryInto, 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(number: N, hash: H) -> Vec where /// Convert block lookup key into block number. /// all block lookup keys start with the block number. -pub fn lookup_key_to_number(key: &[u8]) -> client::error::Result where N: As { +pub fn lookup_key_to_number(key: &[u8]) -> client::error::Result where + N: From +{ 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>( +pub fn remove_number_to_key_mapping>( transaction: &mut DBTransaction, key_lookup_col: Option, number: N, @@ -123,7 +127,7 @@ pub fn remove_number_to_key_mapping>( } /// Remove key mappings. -pub fn remove_key_mappings, H: AsRef<[u8]>>( +pub fn remove_key_mappings, H: AsRef<[u8]>>( transaction: &mut DBTransaction, key_lookup_col: Option, number: N, @@ -135,7 +139,7 @@ pub fn remove_key_mappings, 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 + Clone, H: AsRef<[u8]>>( +pub fn insert_number_to_key_mapping + Clone, H: AsRef<[u8]>>( transaction: &mut DBTransaction, key_lookup_col: Option, number: N, @@ -149,7 +153,7 @@ pub fn insert_number_to_key_mapping + Clone, H: AsRef<[u8]>>( } /// Insert a hash to key mapping in the database. -pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( +pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( transaction: &mut DBTransaction, key_lookup_col: Option, number: N, @@ -171,7 +175,7 @@ pub fn block_id_to_lookup_key( id: BlockId ) -> Result>, client::error::Error> where Block: BlockT, - ::runtime_primitives::traits::NumberFor: As, + ::runtime_primitives::traits::NumberFor: UniqueSaturatedFrom + UniqueSaturatedInto, { let res = match id { BlockId::Number(n) => db.get( diff --git a/substrate/core/client/src/cht.rs b/substrate/core/client/src/cht.rs index 8002f52b6f..42b4654d34 100644 --- a/substrate/core/client/src/cht.rs +++ b/substrate/core/client/src/cht.rs @@ -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( 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( 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( 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( 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::(), + hash_number.saturated_into::() + ) ))?; pairs.push(( encode_cht_key(hash_number).to_vec(), @@ -245,7 +253,10 @@ fn build_pairs( 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::(), + hash_number.saturated_into::() + )) } } @@ -256,12 +267,12 @@ fn build_pairs( /// This is because the genesis hash is assumed to be known /// and including it would be redundant. pub fn start_number(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(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(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>(number: N) -> Vec { - let number: u64 = number.as_(); +pub fn encode_cht_key>(number: N) -> Vec { + // why not just use Encode? + let number: u64 = number.saturated_into(); vec![ (number >> 56) as u8, ((number >> 48) & 0xff) as u8, diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs index 257f120d72..5b849e1352 100644 --- a/substrate/core/client/src/client.rs +++ b/substrate/core/client/src/client.rs @@ -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 = mpsc::UnboundedReceiver = mpsc::UnboundedReceiver>; -type StorageUpdate = <<>::BlockImportOperation as BlockImportOperation>::State as state_machine::Backend>::Transaction; +type StorageUpdate = < + < + >::BlockImportOperation + as BlockImportOperation + >::State as state_machine::Backend>::Transaction; type ChangesUpdate = trie::MemoryDB; /// Execution strategies settings. @@ -146,13 +151,17 @@ pub trait BlockchainEvents { /// 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>; + fn storage_changes_notification_stream(&self, + filter_keys: Option<&[StorageKey]> + ) -> error::Result>; } /// Fetch block body by ID. pub trait BlockBody { /// Get block body by ID. Returns `None` if the body is not stored. - fn block_body(&self, id: &BlockId) -> error::Result::Extrinsic>>>; + fn block_body(&self, + id: &BlockId + ) -> error::Result::Extrinsic>>>; } /// Client info @@ -242,11 +251,15 @@ impl PrePostHeader { pub fn new_in_mem( executor: E, genesis_storage: S, -) -> error::Result, LocalCallExecutor, E>, Block, RA>> - where - E: CodeExecutor + RuntimeInfo, - S: BuildStorage, - Block: BlockT, +) -> error::Result, + LocalCallExecutor, E>, + Block, + RA +>> where + E: CodeExecutor + RuntimeInfo, + S: BuildStorage, + Block: BlockT, { new_with_backend(Arc::new(in_mem::Backend::new()), executor, genesis_storage) } @@ -286,7 +299,10 @@ impl Client 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::(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 Client where /// Get the code at a given block. pub fn code_at(&self, id: &BlockId) -> error::Result> { 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 Client where /// AND returning execution proof. /// /// No changes are made. - pub fn execution_proof(&self, id: &BlockId, method: &str, call_data: &[u8]) -> error::Result<(Vec, Vec>)> { + pub fn execution_proof(&self, + id: &BlockId, + method: &str, + call_data: &[u8] + ) -> error::Result<(Vec, Vec>)> { 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 Client where } /// Get block hash by number. - pub fn block_hash(&self, block_number: <::Header as HeaderT>::Number) -> error::Result> { + pub fn block_hash(&self, + block_number: <::Header as HeaderT>::Number + ) -> error::Result> { 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, cht_size: u64) -> error::Result<(Block::Header, Vec>)> { + pub fn header_proof_with_cht_size(&self, + id: &BlockId, + cht_size: u64 + ) -> error::Result<(Block::Header, Vec>)> { 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::(cht_size, cht_num, ::std::iter::once(block_num), headers)?; Ok((header, proof)) } @@ -460,14 +486,14 @@ impl Client 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::(); + let last_num = self.backend.blockchain().expect_block_number_from_id(&last)?.saturated_into::(); 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::()); + let first = ::std::cmp::max(first, oldest).saturated_into::>(); Ok(Some((first, last))) } @@ -480,20 +506,20 @@ impl Client where key: &StorageKey ) -> error::Result, 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::(); let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?; key_changes::<_, Blake2Hasher>( &config, &*storage, - first.as_(), + first.saturated_into::(), &ChangesTrieAnchorBlockId { hash: convert_hash(&last_hash), number: last_number, }, - self.backend.blockchain().info()?.best_number.as_(), + self.backend.blockchain().info()?.best_number.saturated_into::(), &key.0) - .and_then(|r| r.map(|r| r.map(|(block, tx)| (As::sa(block), tx))).collect::>()) + .and_then(|r| r.map(|r| r.map(|(block, tx)| (block.saturated_into(), tx))).collect::>()) .map_err(|err| error::Error::ChangesTrieAccessFailed(err)) } @@ -543,7 +569,7 @@ impl Client 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 Client where let recording_storage = AccessedRootsRecorder:: { storage, - min: min_number.as_(), + min: min_number.saturated_into::(), required_roots_proofs: Mutex::new(BTreeMap::new()), }; @@ -573,8 +599,12 @@ impl Client 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::(); + let last_number = self.backend.blockchain() + .expect_block_number_from_id(&BlockId::Hash(last))? + .saturated_into::(); let key_changes_proof = key_changes_proof::<_, Blake2Hasher>( &config, &recording_storage, @@ -583,7 +613,7 @@ impl Client where hash: convert_hash(&last), number: last_number, }, - max_number.as_(), + max_number.saturated_into::(), &key.0 ) .map_err(|err| error::Error::from(error::Error::ChangesTrieAccessFailed(err)))?; @@ -628,7 +658,7 @@ impl Client where blocks: Vec> ) -> error::Result>> { 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::(cht_size, cht_num, blocks, roots)?; Ok(proof) @@ -777,7 +807,7 @@ impl Client where }; let hash = import_headers.post().hash(); - let height: u64 = import_headers.post().number().as_(); + let height = (*import_headers.post().number()).saturated_into::(); *self.importing_block.write() = Some(hash); @@ -1201,7 +1231,7 @@ impl Client 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 != ¤t_hash)); current_hash = ancestor_hash; @@ -1224,7 +1254,7 @@ impl Client where /// Prepare in-memory header that is used in execution environment. fn prepare_environment_block(&self, parent: &BlockId) -> error::Result { Ok(<::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)?, diff --git a/substrate/core/client/src/in_mem.rs b/substrate/core/client/src/in_mem.rs index 0050cb9110..558643e887 100644 --- a/substrate/core/client/src/in_mem.rs +++ b/substrate/core/client/src/in_mem.rs @@ -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::(), + changes_trie_root, + changes_trie_update + ); } } @@ -668,7 +674,7 @@ where } fn revert(&self, _n: NumberFor) -> error::Result> { - Ok(As::sa(0)) + Ok(Zero::zero()) } } diff --git a/substrate/core/client/src/light/call_executor.rs b/substrate/core/client/src/light/call_executor.rs index 8f90aaf54e..a45a166674 100644 --- a/substrate/core/client/src/light/call_executor.rs +++ b/substrate/core/client/src/light/call_executor.rs @@ -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( let mut changes = OverlayedChanges::default(); let trie_backend = create_proof_check_backend(root, remote_proof)?; let next_block =
::new( - *request.header.number() + As::sa(1), + *request.header.number() + One::one(), Default::default(), Default::default(), request.header.hash(), diff --git a/substrate/core/client/src/light/fetcher.rs b/substrate/core/client/src/light/fetcher.rs index ff6d3c5c45..29fd6f4c39 100644 --- a/substrate/core/client/src/light/fetcher.rs +++ b/substrate/core/client/src/light/fetcher.rs @@ -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, F> LightDataChecker(), &ChangesTrieAnchorBlockId { hash: convert_hash(&request.last_block.1), - number: request.last_block.0.as_(), + number: request.last_block.0.saturated_into::(), }, - remote_max_block.as_(), + remote_max_block.saturated_into::(), &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::>(), x) + ).collect()) .map_err(|err| ClientError::ChangesTrieAccessFailed(err)) } @@ -438,7 +443,7 @@ impl FetchChecker for LightDataChecker as a changes trie roots storage. -struct RootsStorage<'a, Number: As, Hash: 'a> { +struct RootsStorage<'a, Number: UniqueSaturatedInto + UniqueSaturatedFrom, Hash: 'a> { roots: (Number, &'a [Hash]), prev_roots: BTreeMap, } @@ -446,15 +451,16 @@ struct RootsStorage<'a, Number: As, Hash: 'a> { impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Number, Hash> where H: Hasher, - Number: Send + Sync + Eq + ::std::cmp::Ord + Copy + As, + Number: Send + Sync + Eq + ::std::cmp::Ord + Copy + UniqueSaturatedInto + + UniqueSaturatedFrom, Hash: 'a + Send + Sync + Clone + AsRef<[u8]>, { fn root(&self, _anchor: &ChangesTrieAnchorBlockId, block: u64) -> Result, 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::() { + 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::()) .and_then(|index| self.roots.1.get(index as usize)) .cloned() }; diff --git a/substrate/core/consensus/common/Cargo.toml b/substrate/core/consensus/common/Cargo.toml index 58ea5a1b0a..4031830108 100644 --- a/substrate/core/consensus/common/Cargo.toml +++ b/substrate/core/consensus/common/Cargo.toml @@ -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" diff --git a/substrate/core/consensus/common/src/evaluation.rs b/substrate/core/consensus/common/src/evaluation.rs index 48016b1e94..7f1f527042 100644 --- a/substrate/core/consensus/common/src/evaluation.rs +++ b/substrate/core/consensus/common/src/evaluation.rs @@ -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; 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( )); } - 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::().map(|x| x + 1), + (*proposal.header().number()).checked_into::() + )); } Ok(()) diff --git a/substrate/core/consensus/rhd/src/lib.rs b/substrate/core/consensus/rhd/src/lib.rs index 0afe10ffce..ca4b9120eb 100644 --- a/substrate/core/consensus/rhd/src/lib.rs +++ b/substrate/core/consensus/rhd/src/lib.rs @@ -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 LocalProposer<::Block> for Proposer 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::(), target, misbehavior: match misbehavior { GenericMisbehavior::ProposeOutOfTurn(_, _, _) => continue, diff --git a/substrate/core/finality-grandpa/src/environment.rs b/substrate/core/finality-grandpa/src/environment.rs index cec64b254c..564b7630c4 100644 --- a/substrate/core/finality-grandpa/src/environment.rs +++ b/substrate/core/finality-grandpa/src/environment.rs @@ -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(), diff --git a/substrate/core/finality-grandpa/src/lib.rs b/substrate/core/finality-grandpa/src/lib.rs index 9d808bf4d5..53dd9d2a57 100644 --- a/substrate/core/finality-grandpa/src/lib.rs +++ b/substrate/core/finality-grandpa/src/lib.rs @@ -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>, /// Some local identifier of the voter. diff --git a/substrate/core/network/src/blocks.rs b/substrate/core/network/src/blocks.rs index 60c6886f09..d693afba17 100644 --- a/substrate/core/network/src/blocks.rs +++ b/substrate/core/network/src/blocks.rs @@ -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 BlockRangeState { pub fn len(&self) -> NumberFor { 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 BlockCollection { /// 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, common: NumberFor) -> Option>> { // 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 + >::one(); + let count = (count as u32).into(); let (mut range, downloading) = { let mut downloading_iter = self.blocks.iter().peekable(); let mut prev: Option<(&NumberFor, &BlockRangeState)> = None; @@ -132,7 +132,7 @@ impl BlockCollection { 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 BlockCollection { 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); diff --git a/substrate/core/network/src/protocol.rs b/substrate/core/network/src/protocol.rs index 62c5f508db..cd7a14bdbb 100644 --- a/substrate/core/network/src/protocol.rs +++ b/substrate/core/network/src/protocol.rs @@ -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, H: ExHashT> Protocol { }; 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, H: ExHashT> Protocol { .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::(); 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); diff --git a/substrate/core/network/src/sync.rs b/substrate/core/network/src/sync.rs index 7358672231..fdd36a024d 100644 --- a/substrate/core/network/src/sync.rs +++ b/substrate/core/network/src/sync.rs @@ -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 ChainSync { fn state(&self, best_seen: &Option>) -> 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 ChainSync { 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 ChainSync { } (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 ChainSync { curr_block_num: NumberFor, block_hash_match: bool, ) -> Option<(AncestorSearchState, NumberFor)> { + let two = >::one() + >::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 ChainSync { 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 ChainSync { 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 ChainSync { 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 ChainSync { pub(crate) fn on_block_announce(&mut self, protocol: &mut Context, 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 ChainSync { 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 ChainSync { 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 = self.peers.drain().map(|(id, _)| id).collect(); @@ -839,7 +848,7 @@ impl ChainSync { 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::()), }; peer.state = PeerSyncState::DownloadingNew(range.start); protocol.send_block_request(who, request); diff --git a/substrate/core/rpc/src/chain/number.rs b/substrate/core/rpc/src/chain/number.rs index 2e5af190ea..7983ac6c78 100644 --- a/substrate/core/rpc/src/chain/number.rs +++ b/substrate/core/rpc/src/chain/number.rs @@ -15,6 +15,7 @@ // along with Substrate. If not, see . use serde::Deserialize; +use std::{convert::TryFrom, fmt::Debug}; use primitives::U256; use runtime_primitives::traits; @@ -34,30 +35,28 @@ pub enum NumberOrHex { Hex(U256), } -impl> NumberOrHex { +impl + From + Debug + PartialOrd> NumberOrHex { /// Attempts to convert into concrete block number. /// /// Fails in case hex number is too big. pub fn to_number(self) -> Result { - 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` 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) } } diff --git a/substrate/core/rpc/src/state/mod.rs b/substrate/core/rpc/src/state/mod.rs index 4cb7a3fbd8..0f87faa7a7 100644 --- a/substrate/core/rpc/src/state/mod.rs +++ b/substrate/core/rpc/src/state/mod.rs @@ -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 State 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::()); let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); Ok(QueryStorageRange { hashes: blocks, @@ -281,7 +284,7 @@ impl State 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 State 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::()].clone(); let id = BlockId::Hash(block_hash); let value_at_block = self.client.storage(&id, key)?; changes_map.entry(block) diff --git a/substrate/core/service/src/chain_ops.rs b/substrate/core/service/src/chain_ops.rs index 9f39e8088e..4df3b06cdf 100644 --- a/substrate/core/service/src/chain_ops.rs +++ b/substrate/core/service/src/chain_ops.rs @@ -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( 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( }); 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::(); + let block_: u64 = block.saturated_into::(); let len: u64 = last_ - block_ + 1; output.write(&len.encode())?; } @@ -87,13 +87,13 @@ pub fn export_blocks( }, 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( 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); diff --git a/substrate/core/service/src/lib.rs b/substrate/core/service/src/lib.rs index 2ed9348e52..98a77b68b4 100644 --- a/substrate/core/service/src/lib.rs +++ b/substrate/core/service/src/lib.rs @@ -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 Service { 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::(), + "best" => ?chain_info.best_hash + ); let network_protocol = ::build_network_protocol(&config)?; let transaction_pool = Arc::new( diff --git a/substrate/core/service/test/src/lib.rs b/substrate/core/service/test/src/lib.rs index b0ed0c0fc1..a0f37709bd 100644 --- a/substrate/core/service/test/src/lib.rs +++ b/substrate/core/service/test/src/lib.rs @@ -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, { 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::::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(spec: FactoryChainSpec, authorities: Vec) 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::::new(&temp, spec.clone(), NUM_NODES / 2, 0, authorities, 30600); info!("Checking consensus"); @@ -277,7 +276,7 @@ pub fn consensus(spec: FactoryChainSpec, authorities: Vec) 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(spec: FactoryChainSpec, authorities: Vec) 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() ); } diff --git a/substrate/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs b/substrate/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs index ea9dad2a50..36e17fc277 100644 --- a/substrate/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs +++ b/substrate/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs @@ -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 { 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::(); + 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); diff --git a/substrate/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs b/substrate/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs index a91f4461ff..7f92b20edd 100644 --- a/substrate/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs +++ b/substrate/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs @@ -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 { 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::(); + 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); diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs index bdecfe8981..05938a6a82 100644 --- a/substrate/core/sr-primitives/src/lib.rs +++ b/substrate/core/sr-primitives/src/lib.rs @@ -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 ops::Mul for Permill where - N: Clone + traits::As + ops::Rem + ops::Div - + ops::Mul + ops::Add, + N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add, { type Output = N; fn mul(self, b: N) -> Self::Output { - let million = >::sa(1_000_000); - let part = >::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::(); - // `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 ops::Mul for Perbill where - N: Clone + traits::As + ops::Rem + ops::Div - + ops::Mul + ops::Add + N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add, { type Output = N; fn mul(self, b: N) -> Self::Output { - let billion = >::sa(1_000_000_000); - let part = >::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::(); - // `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] diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs index 92c8026340..8906bbf074 100644 --- a/substrate/core/sr-primitives/src/traits.rs +++ b/substrate/core/sr-primitives/src/traits.rs @@ -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 Convert 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 { - /// 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` +/// and smaller ints. All other conversions are fallible. pub trait SimpleArithmetic: - Zero + One + IntegerSquareRoot + As + + Zero + One + IntegerSquareRoot + + From + From + From + TryInto + TryInto + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + Div + DivAssign + Rem + RemAssign + Shl + Shr + - CheckedShl + - CheckedShr + - CheckedAdd + - CheckedSub + - CheckedMul + - CheckedDiv + - Saturating + - PartialOrd + Ord + Bounded + - HasCompact + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + + Saturating + PartialOrd + Ord + Bounded + + HasCompact + Sized {} impl + + Zero + One + IntegerSquareRoot + + From + From + From + TryInto + TryInto + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + Div + DivAssign + Rem + RemAssign + Shl + Shr + - CheckedShl + - CheckedShr + - CheckedAdd + - CheckedSub + - CheckedMul + - CheckedDiv + - Saturating + - PartialOrd + Ord + Bounded + - HasCompact + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + + Saturating + PartialOrd + 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: 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: Sized { + /// Consume self to return an equivalent value of `T`. + fn unique_saturated_into(self) -> T; +} + +impl + Bounded + Sized> UniqueSaturatedFrom for S { + fn unique_saturated_from(t: T) -> Self { + S::try_from(t).unwrap_or_else(|_| Bounded::max_value()) + } +} + +impl + Sized> UniqueSaturatedInto 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 Saturating for T { + fn saturating_add(self, o: Self) -> Self { + ::saturating_add(self, o) + } + fn saturating_sub(self, o: Self) -> Self { + ::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) -> Self where Self: UniqueSaturatedFrom { + >::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(self) -> T where Self: UniqueSaturatedInto { + >::unique_saturated_into(self) + } +} +impl 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`. + /// + /// 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) -> Option where Self: TryFrom { + >::try_from(t).ok() + } + /// Consume self to return `Some` equivalent value of `Option`. + /// + /// 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(self) -> Option where Self: TryInto { + >::try_into(self).ok() + } +} +impl 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 { diff --git a/substrate/core/state-machine/src/changes_trie/prune.rs b/substrate/core/state-machine/src/changes_trie/prune.rs index bbe5bb573b..09e53315a5 100644 --- a/substrate/core/state-machine/src/changes_trie/prune.rs +++ b/substrate/core/state-machine/src/changes_trie/prune.rs @@ -51,8 +51,7 @@ pub fn prune, H: Hasher, F: FnMut(H::Out)>( min_blocks_to_keep: u64, current_block: &AnchorBlockId, 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), diff --git a/substrate/core/test-runtime/wasm/Cargo.lock b/substrate/core/test-runtime/wasm/Cargo.lock index 2a8f1942a3..df89cba455 100644 --- a/substrate/core/test-runtime/wasm/Cargo.lock +++ b/substrate/core/test-runtime/wasm/Cargo.lock @@ -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", diff --git a/substrate/core/transaction-pool/graph/src/pool.rs b/substrate/core/transaction-pool/graph/src/pool.rs index 121e3ddf00..78d06eabb5 100644 --- a/substrate/core/transaction-pool/graph/src/pool.rs +++ b/substrate/core/transaction-pool/graph/src/pool.rs @@ -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 Pool { priority, requires, provides, - valid_till: block_number.as_().saturating_add(longevity), + valid_till: block_number + .saturated_into::() + .saturating_add(longevity), }) }, TransactionValidity::Invalid(e) => { @@ -337,7 +339,7 @@ impl Pool { pub fn clear_stale(&self, at: &BlockId) -> 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::(); let now = time::Instant::now(); let to_remove = { self.ready() diff --git a/substrate/node-template/runtime/wasm/Cargo.lock b/substrate/node-template/runtime/wasm/Cargo.lock index cfbf85fbf2..e458c165c0 100644 --- a/substrate/node-template/runtime/wasm/Cargo.lock +++ b/substrate/node-template/runtime/wasm/Cargo.lock @@ -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", diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index e74db4629d..a285a246cc 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -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, }; diff --git a/substrate/node/runtime/wasm/Cargo.lock b/substrate/node/runtime/wasm/Cargo.lock index cee874bf50..50037f709e 100644 --- a/substrate/node/runtime/wasm/Cargo.lock +++ b/substrate/node/runtime/wasm/Cargo.lock @@ -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", diff --git a/substrate/srml/aura/src/lib.rs b/substrate/srml/aura/src/lib.rs index e5eb3674cd..646ad972d0 100644 --- a/substrate/srml/aura/src/lib.rs +++ b/substrate/srml/aura/src/lib.rs @@ -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 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 Module { /// 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. - >::minimum_period().as_().saturating_mul(2) + >::minimum_period().saturating_mul(2.into()) } fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) { let last = Self::last(); ::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::(), + skipped: skipped_slots.saturated_into::(), }) } } impl OnTimestampSet for Module { fn on_timestamp_set(moment: T::Moment) { - Self::on_timestamp_set::(moment, T::Moment::sa(Self::slot_duration())) + Self::on_timestamp_set::(moment, Self::slot_duration()) } } @@ -265,9 +263,9 @@ impl ProvideInherent for Module { _ => 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(()) diff --git a/substrate/srml/babe/src/lib.rs b/substrate/srml/babe/src/lib.rs index e9b5426221..3e36481151 100644 --- a/substrate/srml/babe/src/lib.rs +++ b/substrate/srml/babe/src/lib.rs @@ -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 Module { /// 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. - >::minimum_period().as_().saturating_mul(2) + >::minimum_period().saturating_mul(2.into()) } } @@ -142,10 +142,8 @@ impl ProvideInherent for Module { _ => return Ok(()), }; - let timestamp_based_slot = timestamp.as_() / Self::slot_duration(); - + let timestamp_based_slot = (timestamp / Self::slot_duration()).saturated_into::(); let seal_slot = data.babe_inherent_data()?; - if timestamp_based_slot == seal_slot { Ok(()) } else { diff --git a/substrate/srml/balances/src/lib.rs b/substrate/srml/balances/src/lib.rs index 90f774dbf3..9fe93a9d4a 100644 --- a/substrate/srml/balances/src/lib.rs +++ b/substrate/srml/balances/src/lib.rs @@ -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: 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; /// 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: system::Trait { pub trait Trait: 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; /// 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 { pub per_block: Balance, } -impl> VestingSchedule { +impl VestingSchedule { /// Amount locked at block `n`. - pub fn locked_at>(&self, n: BlockNumber) -> Balance { - if let Some(x) = Balance::sa(n.as_()).checked_mul(&self.per_block) { + pub fn locked_at(&self, n: BlockNumber) -> Balance + where Balance: From + { + 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| { 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 = >::from(begin); + let length = >::from(length); config.balances.iter() .find(|&&(ref w, _)| w == who) @@ -380,7 +382,8 @@ impl, I: Instance> Module { /// 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(>::block_number())) + Self::free_balance(who) + .min(v.locked_at::(>::block_number())) } else { Zero::zero() } @@ -1013,7 +1016,7 @@ where impl, I: Instance> MakePayment for Module { fn make_payment(transactor: &T::AccountId, encoded_len: usize) -> Result { - let encoded_len = >::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, diff --git a/substrate/srml/contract/src/account_db.rs b/substrate/srml/contract/src/account_db.rs index df63ccc479..21f2972893 100644 --- a/substrate/srml/contract/src/account_db.rs +++ b/substrate/srml/contract/src/account_db.rs @@ -140,10 +140,10 @@ impl AccountDb 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)); diff --git a/substrate/srml/contract/src/gas.rs b/substrate/srml/contract/src/gas.rs index f42b0919f3..1ea5196344 100644 --- a/substrate/srml/contract/src/gas.rs +++ b/substrate/srml/contract/src/gas.rs @@ -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( // Buy the specified amount of gas. let gas_price = >::gas_price(); - let cost = >>::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( >::mutate(|block_gas_spent| *block_gas_spent += gas_spent); // Refund gas left by the price it was bought at. - let refund = >>::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( /// 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(gas_price: BalanceOf, balance: BalanceOf) -> T::Gas { - let amount_in_gas: BalanceOf = balance / gas_price; - >>::sa(amount_in_gas) + (balance / gas_price).saturated_into::() } /// A simple utility macro that helps to match against a diff --git a/substrate/srml/contract/src/lib.rs b/substrate/srml/contract/src/lib.rs index 0cd3b0a325..b9412b3619 100644 --- a/substrate/srml/contract/src/lib.rs +++ b/substrate/srml/contract/src/lib.rs @@ -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 { /// 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 { pub struct TombstoneContractInfo(T::Hash); impl TombstoneContractInfo { - fn new(storage_root: Vec, storage_size: u64, code_hash: CodeHash) -> Self { + fn new(storage_root: Vec, storage_size: u32, code_hash: CodeHash) -> 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 = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +pub type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: timestamp::Trait { type Currency: Currency; @@ -263,8 +263,8 @@ pub trait Trait: timestamp::Trait { /// The overarching event type. type Event: From> + Into<::Event>; - // `As` is needed for wasm-utils - type Gas: Parameter + Default + Codec + SimpleArithmetic + Bounded + Copy + As> + As + As; + type Gas: Parameter + Default + Codec + SimpleArithmetic + Bounded + Copy + + Into> + TryFrom>; /// A function type to get the contract address given the creator. type DetermineContractAddress: ContractAddressFor, Self::AccountId>; @@ -310,10 +310,10 @@ where pub struct DefaultDispatchFeeComputor(PhantomData); impl ComputeDispatchFee> for DefaultDispatchFeeComputor { fn compute_dispatch_fee(call: &T::Call) -> BalanceOf { - let encoded_len = call.using_encoded(|encoded| encoded.len()); + let encoded_len = call.using_encoded(|encoded| encoded.len() as u32); let base_fee = >::transaction_base_fee(); let byte_fee = >::transaction_byte_fee(); - base_fee + byte_fee * as As>::sa(encoded_len as u64) + base_fee + byte_fee * encoded_len.into() } } @@ -553,7 +553,7 @@ decl_storage! { TombstoneDeposit get(tombstone_deposit) config(): BalanceOf; /// 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; /// 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; /// The fee required to create a contract instance. - ContractFee get(contract_fee) config(): BalanceOf = BalanceOf::::sa(21); + ContractFee get(contract_fee) config(): BalanceOf = 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 = BalanceOf::::sa(1); + GasPrice get(gas_price) config(): BalanceOf = 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 { pub enable_println: bool, } -impl> Default for Schedule { +impl> Default for Schedule { fn default() -> Schedule { 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, diff --git a/substrate/srml/contract/src/rent.rs b/substrate/srml/contract/src/rent.rs index 5466e2553d..aacbb4ab7f 100644 --- a/substrate/srml/contract/src/rent.rs +++ b/substrate/srml/contract/src/rent.rs @@ -15,7 +15,8 @@ // along with Substrate. If not, see . 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( let fee_per_block = { let free_storage = balance .checked_div(&>::rent_deposit_offset()) - .unwrap_or(>::sa(0)); + .unwrap_or_else(Zero::zero); let effective_storage_size = - >::sa(contract.storage_size).saturating_sub(free_storage); + >::from(contract.storage_size).saturating_sub(free_storage); effective_storage_size .checked_mul(&>::rent_byte_price()) @@ -95,7 +96,7 @@ fn try_evict_or_and_pay_rent( let subsistence_threshold = T::Currency::minimum_balance() + >::tombstone_deposit(); let dues = fee_per_block - .checked_mul(&>::sa(blocks_passed.as_())) + .checked_mul(&blocks_passed.saturated_into::().into()) .unwrap_or(>::max_value()); let dues_limited = dues.min(contract.rent_allowance); diff --git a/substrate/srml/contract/src/tests.rs b/substrate/srml/contract/src/tests.rs index 4eed6777b4..a14819850e 100644 --- a/substrate/srml/contract/src/tests.rs +++ b/substrate/srml/contract/src/tests.rs @@ -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(), - ::Balance::sa(1_000u64).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); let bob_contract = super::ContractInfoOf::::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(), - ::Balance::sa(1_000u64).encode() // rent allowance + ::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(), - ::Balance::sa(1_000u64).encode() // rent allowance + ::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(), - ::Balance::sa(1_000u64).encode() // rent allowance + ::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(), - ::Balance::sa(100u64).encode() // rent allowance + ::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(), - ::Balance::sa(1_000u64).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); // Trigger rent must have no effect diff --git a/substrate/srml/contract/src/wasm/code_cache.rs b/substrate/srml/contract/src/wasm/code_cache.rs index 0c71fe8cb5..da92272c38 100644 --- a/substrate/srml/contract/src/wasm/code_cache.rs +++ b/substrate/srml/contract/src/wasm/code_cache.rs @@ -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 Token for PutCodeToken { type Metadata = Schedule; fn calculate_amount(&self, metadata: &Schedule) -> T::Gas { - let code_len_in_gas = >::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( // 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"); diff --git a/substrate/srml/contract/src/wasm/env_def/macros.rs b/substrate/srml/contract/src/wasm/env_def/macros.rs index bfb42d19d0..32d02f5abe 100644 --- a/substrate/srml/contract/src/wasm/env_def/macros.rs +++ b/substrate/srml/contract/src/wasm/env_def/macros.rs @@ -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!( ext_gas (_ctx, amount: u32) => { - let amount = <::Gas as As>::sa(amount); + let amount = ::Gas::from(amount); if !amount.is_zero() { Ok(()) } else { @@ -308,7 +308,7 @@ mod tests { define_env!(Env, , ext_gas( _ctx, amount: u32 ) => { - let amount = <::Gas as As>::sa(amount); + let amount = ::Gas::from(amount); if !amount.is_zero() { Ok(()) } else { diff --git a/substrate/srml/contract/src/wasm/prepare.rs b/substrate/srml/contract/src/wasm/prepare.rs index 94a38ef588..d780cc1a28 100644 --- a/substrate/srml/contract/src/wasm/prepare.rs +++ b/substrate/srml/contract/src/wasm/prepare.rs @@ -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, } -impl<'a, Gas: 'a + As + Clone> ContractModule<'a, Gas> { +impl<'a, Gas: 'a + From + UniqueSaturatedInto + 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 + 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 diff --git a/substrate/srml/contract/src/wasm/runtime.rs b/substrate/srml/contract/src/wasm/runtime.rs index 6327d8f2ce..b6f857269e 100644 --- a/substrate/srml/contract/src/wasm/runtime.rs +++ b/substrate/srml/contract/src/wasm/runtime.rs @@ -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 Token for RuntimeToken { fn calculate_amount(&self, metadata: &Schedule) -> T::Gas { use self::RuntimeToken::*; let value = match *self { - Explicit(amount) => Some(>::sa(amount)), + Explicit(amount) => Some(amount.into()), ReadMemory(byte_count) => metadata .sandbox_data_read_cost - .checked_mul(&>::sa(byte_count)), + .checked_mul(&byte_count.into()), WriteMemory(byte_count) => metadata .sandbox_data_write_cost - .checked_mul(&>::sa(byte_count)), + .checked_mul(&byte_count.into()), ReturnData(byte_count) => metadata .return_data_per_byte_cost - .checked_mul(&>::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(&>::sa(data_byte_count)); + .checked_mul(&data_byte_count.into()); let topics_cost = metadata .event_per_topic_cost - .checked_mul(&>::sa(topic_count)); + .checked_mul(&topic_count.into()); data_cost .and_then(|data_cost| { @@ -340,7 +340,7 @@ define_env!(Env, , let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() } else { - <::Gas as As>::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, , let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() } else { - <::Gas as As>::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, , // 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(()) }, diff --git a/substrate/srml/council/src/seats.rs b/substrate/srml/council/src/seats.rs index 9ace6227da..fb93157981 100644 --- a/substrate/srml/council/src/seats.rs +++ b/substrate/srml/council/src/seats.rs @@ -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::::sa(voters.len() as u64); + let bad_presentation_punishment = Self::present_slash_per_voter() * BalanceOf::::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 = BalanceOf::::sa(9); + pub CandidacyBond get(candidacy_bond) config(): BalanceOf = 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; /// The punishment, per voter, if you provide an invalid presentation. - pub PresentSlashPerVoter get(present_slash_per_voter) config(): BalanceOf = BalanceOf::::sa(1); + pub PresentSlashPerVoter get(present_slash_per_voter) config(): BalanceOf = 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; diff --git a/substrate/srml/council/src/voting.rs b/substrate/srml/council/src/voting.rs index 22b4b9639c..0137cd6d2f 100644 --- a/substrate/srml/council/src/voting.rs +++ b/substrate/srml/council/src/voting.rs @@ -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 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; pub ProposalVoters get(proposal_voters): map T::Hash => Vec; diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs index b72a3add2e..c2a9b849f6 100644 --- a/substrate/srml/democracy/src/lib.rs +++ b/substrate/srml/democracy/src/lib.rs @@ -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 = >::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, Vec)>; /// 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; /// 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 Module { /// Get the amount locked in support of `proposal`; `None` if proposal isn't a valid proposal /// index. pub fn locked_for(proposal: PropIndex) -> Option> { - Self::deposit_of(proposal).map(|(d, l)| d * BalanceOf::::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 Module { )) .map(|(bal, vote)| if vote.is_aye() { - (bal * BalanceOf::::sa(vote.multiplier() as u64), Zero::zero(), bal) + (bal * (vote.multiplier() as u32).into(), Zero::zero(), bal) } else { - (Zero::zero(), bal * BalanceOf::::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 Module { .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::::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 Module { { // 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()); } diff --git a/substrate/srml/finality-tracker/src/lib.rs b/substrate/srml/finality-tracker/src/lib.rs index 91beefa66b..2276ad3155 100644 --- a/substrate/srml/finality-tracker/src/lib.rs +++ b/substrate/srml/finality-tracker/src/lib.rs @@ -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; @@ -154,7 +154,7 @@ impl Module { // 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::()); for drained in recent.drain(..to_prune) { let idx = ordered.binary_search(&drained) @@ -188,13 +188,13 @@ impl Module { } }; - let our_window_size = recent.len(); + let our_window_size = recent.len() as u32; ::RecentHints::put(recent); ::OrderedHints::put(ordered); ::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::::block_number(); let latency = Self::report_latency(); diff --git a/substrate/srml/grandpa/src/lib.rs b/substrate/srml/grandpa/src/lib.rs index e9886eddb1..5425ace8bb 100644 --- a/substrate/srml/grandpa/src/lib.rs +++ b/substrate/srml/grandpa/src/lib.rs @@ -275,8 +275,6 @@ impl Module { in_blocks: T::BlockNumber, forced: Option, ) -> Result { - use primitives::traits::As; - if Self::pending_change().is_none() { let scheduled_at = system::ChainContext::::default().current_height(); @@ -287,7 +285,7 @@ impl Module { // only allow the next forced change when twice the window has passed since // this one. - >::put(scheduled_at + in_blocks * T::BlockNumber::sa(2)); + >::put(scheduled_at + in_blocks * 2.into()); } >::put(StoredPendingChange { diff --git a/substrate/srml/indices/src/address.rs b/substrate/srml/indices/src/address.rs index c7709e3bec..123b8bca89 100644 --- a/substrate/srml/indices/src/address.rs +++ b/substrate/srml/indices/src/address.rs @@ -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(a: T, b: T) -> Option { impl Decode for Address where AccountId: Member + Decode, - AccountIndex: Member + Decode + PartialOrd + Ord + As + As + As + Copy, + AccountIndex: Member + Decode + PartialOrd + Ord + From + Copy, { fn decode(input: &mut I) -> Option { 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 Decode for Address where impl Encode for Address where AccountId: Member + Encode, - AccountIndex: Member + Encode + PartialOrd + Ord + As + As + As + Copy, + AccountIndex: Member + Encode + PartialOrd + Ord + Copy + From + TryInto, { fn encode_to(&self, dest: &mut T) { match *self { @@ -83,19 +90,26 @@ impl Encode for Address 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::::as_(i)); - } - Address::Index(i) if i >= As::sa(0xf0u32) => { - dest.push_byte(252); - dest.push(&As::::as_(i)); - } - Address::Index(i) => dest.push_byte(As::::as_(i)), + Address::Index(i) => { + let maybe_u32: Result = 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); + } + }, } } } diff --git a/substrate/srml/indices/src/lib.rs b/substrate/srml/indices/src/lib.rs index 4a6010f800..509e5c1133 100644 --- a/substrate/srml/indices/src/lib.rs +++ b/substrate/srml/indices/src/lib.rs @@ -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 = RawAddress<::AccountId, ::AccountIndex>; /// Turn an Id into an Index, or None for the purpose of getting /// a hint at a possibly desired index. -pub trait ResolveHint> { +pub trait ResolveHint { /// 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; @@ -47,9 +47,11 @@ pub trait ResolveHint> { /// Simple encode-based resolve hint implemenntation. pub struct SimpleResolveHint(PhantomData<(AccountId, AccountIndex)>); -impl> ResolveHint for SimpleResolveHint { +impl> + ResolveHint for SimpleResolveHint +{ fn resolve_hint(who: &AccountId) -> Option { - 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> ResolveHint + As + As + As + As + Copy; + type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + Copy; /// Whether an account is dead or not. type IsDeadAccount: IsDeadAccount; @@ -92,15 +94,18 @@ decl_storage! { trait Store for Module as Indices { /// The next free enumeration set. pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig| { - 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| { - (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::>() }): map T::AccountIndex => Vec; @@ -117,7 +122,7 @@ impl Module { pub fn lookup_index(index: T::AccountIndex) -> Option { 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 Module { 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 = (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) -> Option { + pub fn lookup_address( + a: address::Address + ) -> Option { match a { address::Address::Id(i) => Some(i), address::Address::Index(i) => Self::lookup_index(i), @@ -140,7 +151,7 @@ impl Module { // PUBLIC MUTABLES (DANGEROUS) fn enum_set_size() -> T::AccountIndex { - T::AccountIndex::sa(ENUM_SET_SIZE) + ENUM_SET_SIZE.into() } } @@ -153,36 +164,38 @@ impl OnNewAccount for Module { // 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(); - >::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(); + >::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 { >::put(set_index + One::one()); } diff --git a/substrate/srml/session/src/lib.rs b/substrate/srml/session/src/lib.rs index 255bb4f647..d13795e4bb 100644 --- a/substrate/srml/session/src/lib.rs +++ b/substrate/srml/session/src/lib.rs @@ -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; /// 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; diff --git a/substrate/srml/staking/src/lib.rs b/substrate/srml/staking/src/lib.rs index 93bd941092..1901752666 100644 --- a/substrate/srml/staking/src/lib.rs +++ b/substrate/srml/staking/src/lib.rs @@ -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 = <::Currency as Currency< = (::AccountId, ExtendedBalance); type Assignment = (::AccountId, ExtendedBalance, BalanceOf); -type ExpoMap = BTreeMap::<::AccountId, Exposure<::AccountId, BalanceOf>>; +type ExpoMap = BTreeMap<::AccountId, Exposure<::AccountId, BalanceOf>>; 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 Module { 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() * >::sa(per65536) / >::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 = per65536.saturated_into::().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 Module { 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::::sa(len); + let len = validators.len() as u32; // validators length can never overflow u64 + let len: BalanceOf = len.into(); let total_minted = reward * len; let total_rewarded_stake = Self::slot_stake() * len; T::OnRewardMinted::on_dilution(total_minted, total_rewarded_stake); diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs index b009785011..9018b109e8 100644 --- a/substrate/srml/system/src/lib.rs +++ b/substrate/srml/system/src/lib.rs @@ -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); /// 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 Module { let mut digest = >::take(); let extrinsics_root = >::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::(); + 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. diff --git a/substrate/srml/timestamp/src/lib.rs b/substrate/srml/timestamp/src/lib.rs index bc998a8539..24750215d1 100644 --- a/substrate/srml/timestamp/src/lib.rs +++ b/substrate/srml/timestamp/src/lib.rs @@ -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 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 ProvideInherent for Module { const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(data: &InherentData) -> Option { - 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() + >::get()); + let next_time = cmp::max(data, Self::now() + >::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::(), _ => return Ok(()), - }.as_(); + }; let data = extract_inherent_data(data).map_err(|e| InherentError::Other(e))?; - let minimum = (Self::now() + >::get()).as_(); + let minimum = (Self::now() + >::get()).saturated_into::(); if t > data + MAX_TIMESTAMP_DRIFT { Err(InherentError::Other("Timestamp too far in future to accept".into())) } else if t < minimum {