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

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

* Remove As from Balances trait

* Remove As from Aura module

* Remove As from Babe module

* Expunge `As` from contract

* Council module

* Democracy

* Finality tracker

* Grandpa

* First bit of indices

* indices

* Line lengths

* session

* system

* Staking

* Square up all other uses of As.

* RHD update

* Fix build/test

* Remove As trait

* line widths

* Remove final As ref

* Update srml/staking/src/lib.rs

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

* Update core/client/src/cht.rs

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

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

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

* Apply suggestions from code review

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

* whitespace

* Apply suggestions from code review

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

* Bring back u32 check for number on CLI
This commit is contained in:
Gavin Wood
2019-05-22 23:11:38 +01:00
committed by GitHub
parent 36987c0205
commit 3860d7c810
60 changed files with 695 additions and 491 deletions
+34 -20
View File
@@ -18,7 +18,8 @@
#[cfg(feature = "std")]
use std::fmt;
use crate::{Member, Decode, Encode, As, Input, Output};
use rstd::convert::TryInto;
use crate::{Member, Decode, Encode, Input, Output};
/// An indices-aware address, which can be either a direct `AccountId` or
/// an index.
@@ -59,14 +60,20 @@ fn need_more_than<T: PartialOrd>(a: T, b: T) -> Option<T> {
impl<AccountId, AccountIndex> Decode for Address<AccountId, AccountIndex> where
AccountId: Member + Decode,
AccountIndex: Member + Decode + PartialOrd<AccountIndex> + Ord + As<u32> + As<u16> + As<u8> + Copy,
AccountIndex: Member + Decode + PartialOrd<AccountIndex> + Ord + From<u32> + Copy,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(match input.read_byte()? {
x @ 0x00...0xef => Address::Index(As::sa(x)),
0xfc => Address::Index(As::sa(need_more_than(0xef, u16::decode(input)?)?)),
0xfd => Address::Index(As::sa(need_more_than(0xffff, u32::decode(input)?)?)),
0xfe => Address::Index(need_more_than(As::sa(0xffffffffu32), Decode::decode(input)?)?),
x @ 0x00...0xef => Address::Index(AccountIndex::from(x as u32)),
0xfc => Address::Index(AccountIndex::from(
need_more_than(0xef, u16::decode(input)?)? as u32
)),
0xfd => Address::Index(AccountIndex::from(
need_more_than(0xffff, u32::decode(input)?)?
)),
0xfe => Address::Index(
need_more_than(0xffffffffu32.into(), Decode::decode(input)?)?
),
0xff => Address::Id(Decode::decode(input)?),
_ => return None,
})
@@ -75,7 +82,7 @@ impl<AccountId, AccountIndex> Decode for Address<AccountId, AccountIndex> where
impl<AccountId, AccountIndex> Encode for Address<AccountId, AccountIndex> where
AccountId: Member + Encode,
AccountIndex: Member + Encode + PartialOrd<AccountIndex> + Ord + As<u32> + As<u16> + As<u8> + Copy,
AccountIndex: Member + Encode + PartialOrd<AccountIndex> + Ord + Copy + From<u32> + TryInto<u32>,
{
fn encode_to<T: Output>(&self, dest: &mut T) {
match *self {
@@ -83,19 +90,26 @@ impl<AccountId, AccountIndex> Encode for Address<AccountId, AccountIndex> where
dest.push_byte(255);
dest.push(i);
}
Address::Index(i) if i > As::sa(0xffffffffu32) => {
dest.push_byte(254);
dest.push(&i);
}
Address::Index(i) if i > As::sa(0xffffu32) => {
dest.push_byte(253);
dest.push(&As::<u32>::as_(i));
}
Address::Index(i) if i >= As::sa(0xf0u32) => {
dest.push_byte(252);
dest.push(&As::<u16>::as_(i));
}
Address::Index(i) => dest.push_byte(As::<u8>::as_(i)),
Address::Index(i) => {
let maybe_u32: Result<u32, _> = i.try_into();
if let Ok(x) = maybe_u32 {
if x > 0xffff {
dest.push_byte(253);
dest.push(&x);
}
else if x >= 0xf0 {
dest.push_byte(252);
dest.push(&(x as u16));
}
else {
dest.push_byte(x as u8);
}
} else {
dest.push_byte(254);
dest.push(&i);
}
},
}
}
}
+40 -27
View File
@@ -19,10 +19,10 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::{prelude::*, result, marker::PhantomData};
use rstd::{prelude::*, result, marker::PhantomData, convert::TryInto};
use parity_codec::{Encode, Decode, Codec, Input, Output};
use srml_support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage};
use primitives::traits::{One, SimpleArithmetic, As, StaticLookup, Member};
use primitives::traits::{One, SimpleArithmetic, StaticLookup, Member};
use system::{IsDeadAccount, OnNewAccount};
use self::address::Address as RawAddress;
@@ -33,13 +33,13 @@ pub mod address;
mod tests;
/// Number of account IDs stored per enum set.
const ENUM_SET_SIZE: usize = 64;
const ENUM_SET_SIZE: u32 = 64;
pub type Address<T> = RawAddress<<T as system::Trait>::AccountId, <T as Trait>::AccountIndex>;
/// Turn an Id into an Index, or None for the purpose of getting
/// a hint at a possibly desired index.
pub trait ResolveHint<AccountId: Encode, AccountIndex: As<usize>> {
pub trait ResolveHint<AccountId, AccountIndex> {
/// Turn an Id into an Index, or None for the purpose of getting
/// a hint at a possibly desired index.
fn resolve_hint(who: &AccountId) -> Option<AccountIndex>;
@@ -47,9 +47,11 @@ pub trait ResolveHint<AccountId: Encode, AccountIndex: As<usize>> {
/// Simple encode-based resolve hint implemenntation.
pub struct SimpleResolveHint<AccountId, AccountIndex>(PhantomData<(AccountId, AccountIndex)>);
impl<AccountId: Encode, AccountIndex: As<usize>> ResolveHint<AccountId, AccountIndex> for SimpleResolveHint<AccountId, AccountIndex> {
impl<AccountId: Encode, AccountIndex: From<u32>>
ResolveHint<AccountId, AccountIndex> for SimpleResolveHint<AccountId, AccountIndex>
{
fn resolve_hint(who: &AccountId) -> Option<AccountIndex> {
Some(AccountIndex::sa(who.using_encoded(|e| e[0] as usize + e[1] as usize * 256)))
Some(AccountIndex::from(who.using_encoded(|e| e[0] as u32 + e[1] as u32 * 256)))
}
}
@@ -57,7 +59,7 @@ impl<AccountId: Encode, AccountIndex: As<usize>> ResolveHint<AccountId, AccountI
pub trait Trait: system::Trait {
/// Type used for storing an account's index; implies the maximum number of accounts the system
/// can hold.
type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + As<u8> + As<u16> + As<u32> + As<u64> + As<usize> + Copy;
type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + Copy;
/// Whether an account is dead or not.
type IsDeadAccount: IsDeadAccount<Self::AccountId>;
@@ -92,15 +94,18 @@ decl_storage! {
trait Store for Module<T: Trait> as Indices {
/// The next free enumeration set.
pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig<T>| {
T::AccountIndex::sa(config.ids.len() / ENUM_SET_SIZE)
(config.ids.len() as u32 / ENUM_SET_SIZE).into()
}): T::AccountIndex;
/// The enumeration sets.
pub EnumSet get(enum_set) build(|config: &GenesisConfig<T>| {
(0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE)
(0..((config.ids.len() as u32) + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE)
.map(|i| (
T::AccountIndex::sa(i),
config.ids[i * ENUM_SET_SIZE..config.ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned(),
i.into(),
config.ids[
(i * ENUM_SET_SIZE) as usize..
config.ids.len().min(((i + 1) * ENUM_SET_SIZE) as usize)
].to_owned(),
))
.collect::<Vec<_>>()
}): map T::AccountIndex => Vec<T::AccountId>;
@@ -117,7 +122,7 @@ impl<T: Trait> Module<T> {
pub fn lookup_index(index: T::AccountIndex) -> Option<T::AccountId> {
let enum_set_size = Self::enum_set_size();
let set = Self::enum_set(index / enum_set_size);
let i: usize = (index % enum_set_size).as_();
let i: usize = (index % enum_set_size).try_into().ok()?;
set.get(i).cloned()
}
@@ -125,12 +130,18 @@ impl<T: Trait> Module<T> {
pub fn can_reclaim(try_index: T::AccountIndex) -> bool {
let enum_set_size = Self::enum_set_size();
let try_set = Self::enum_set(try_index / enum_set_size);
let i = (try_index % enum_set_size).as_();
i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i])
let maybe_usize: Result<usize, _> = (try_index % enum_set_size).try_into();
if let Ok(i) = maybe_usize {
i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i])
} else {
false
}
}
/// Lookup an address to get an Id, if there's one there.
pub fn lookup_address(a: address::Address<T::AccountId, T::AccountIndex>) -> Option<T::AccountId> {
pub fn lookup_address(
a: address::Address<T::AccountId, T::AccountIndex>
) -> Option<T::AccountId> {
match a {
address::Address::Id(i) => Some(i),
address::Address::Index(i) => Self::lookup_index(i),
@@ -140,7 +151,7 @@ impl<T: Trait> Module<T> {
// PUBLIC MUTABLES (DANGEROUS)
fn enum_set_size() -> T::AccountIndex {
T::AccountIndex::sa(ENUM_SET_SIZE)
ENUM_SET_SIZE.into()
}
}
@@ -153,36 +164,38 @@ impl<T: Trait> OnNewAccount<T::AccountId> for Module<T> {
// then check to see if this account id identifies a dead account index.
let set_index = try_index / enum_set_size;
let mut try_set = Self::enum_set(set_index);
let item_index = (try_index % enum_set_size).as_();
if item_index < try_set.len() {
if T::IsDeadAccount::is_dead_account(&try_set[item_index]) {
// yup - this index refers to a dead account. can be reused.
try_set[item_index] = who.clone();
<EnumSet<T>>::insert(set_index, try_set);
if let Ok(item_index) = (try_index % enum_set_size).try_into() {
if item_index < try_set.len() {
if T::IsDeadAccount::is_dead_account(&try_set[item_index]) {
// yup - this index refers to a dead account. can be reused.
try_set[item_index] = who.clone();
<EnumSet<T>>::insert(set_index, try_set);
return
return
}
}
}
}
// insert normally as a back up
let mut set_index = next_set_index;
// defensive only: this loop should never iterate since we keep NextEnumSet up to date later.
// defensive only: this loop should never iterate since we keep NextEnumSet up to date
// later.
let mut set = loop {
let set = Self::enum_set(set_index);
if set.len() < ENUM_SET_SIZE {
if set.len() < ENUM_SET_SIZE as usize {
break set;
}
set_index += One::one();
};
let index = T::AccountIndex::sa(set_index.as_() * ENUM_SET_SIZE + set.len());
let index = set_index * enum_set_size + T::AccountIndex::from(set.len() as u32);
// update set.
set.push(who.clone());
// keep NextEnumSet up to date
if set.len() == ENUM_SET_SIZE {
if set.len() == ENUM_SET_SIZE as usize {
<NextEnumSet<T>>::put(set_index + One::one());
}