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