mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-07 18:58:01 +00:00
Per-things trait. (#4904)
* Give perthigns the trait it always deserved.
* Make staking and phragmen work with the new generic per_thing
* Make everything work together 🔨
* a bit of cleanup
* Clean usage
* Bump.
* Fix name
* fix grumbles
* hopefully fix the ui test
* Some grumbles
* revamp traits again
* Better naming again.
This commit is contained in:
@@ -12,7 +12,7 @@ use sp_std::prelude::*;
|
||||
use sp_core::OpaqueMetadata;
|
||||
use sp_runtime::{
|
||||
ApplyExtrinsicResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
|
||||
impl_opaque_keys, MultiSignature
|
||||
impl_opaque_keys, MultiSignature,
|
||||
};
|
||||
use sp_runtime::traits::{
|
||||
BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto, IdentifyAccount
|
||||
|
||||
@@ -31,8 +31,8 @@ pub use node_primitives::{AccountId, Signature};
|
||||
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_runtime::{
|
||||
Permill, Perbill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str,
|
||||
BenchmarkResults,
|
||||
Permill, Perbill, Percent, ApplyExtrinsicResult, BenchmarkResults,
|
||||
impl_opaque_keys, generic, create_runtime_str,
|
||||
};
|
||||
use sp_runtime::curve::PiecewiseLinear;
|
||||
use sp_runtime::transaction_validity::TransactionValidity;
|
||||
@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
// implementation changes and behavior does not, then leave spec_version as
|
||||
// is and increment impl_version.
|
||||
spec_version: 216,
|
||||
impl_version: 2,
|
||||
impl_version: 3,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
|
||||
@@ -37,15 +37,15 @@ use sp_consensus::block_import::BlockImport;
|
||||
use codec::{Decode, Encode};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::{
|
||||
Block as BlockT, Header as HeaderT, SimpleArithmetic, One, Zero,
|
||||
Block as BlockT, Header as HeaderT, AtLeast32Bit, One, Zero,
|
||||
};
|
||||
|
||||
pub trait RuntimeAdapter {
|
||||
type AccountId: Display;
|
||||
type Balance: Display + SimpleArithmetic + From<Self::Number>;
|
||||
type Balance: Display + AtLeast32Bit + From<Self::Number>;
|
||||
type Block: BlockT;
|
||||
type Index: Copy;
|
||||
type Number: Display + PartialOrd + SimpleArithmetic + Zero + One;
|
||||
type Number: Display + PartialOrd + AtLeast32Bit + Zero + One;
|
||||
type Phase: Copy;
|
||||
type Secret;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ use codec::Encode;
|
||||
use sp_trie;
|
||||
|
||||
use sp_core::{H256, convert_hash};
|
||||
use sp_runtime::traits::{Header as HeaderT, SimpleArithmetic, Zero, One};
|
||||
use sp_runtime::traits::{Header as HeaderT, AtLeast32Bit, Zero, One};
|
||||
use sp_state_machine::{
|
||||
MemoryDB, TrieBackend, Backend as StateBackend, StorageProof, InMemoryBackend,
|
||||
prove_read_on_trie_backend, read_proof_check, read_proof_check_on_proving_backend
|
||||
@@ -48,7 +48,7 @@ pub fn size<N: From<u32>>() -> N {
|
||||
/// Returns Some(cht_number) if CHT is need to be built when the block with given number is canonized.
|
||||
pub fn is_build_required<N>(cht_size: N, block_num: N) -> Option<N>
|
||||
where
|
||||
N: Clone + SimpleArithmetic,
|
||||
N: Clone + AtLeast32Bit,
|
||||
{
|
||||
let block_cht_num = block_to_cht_number(cht_size.clone(), block_num.clone())?;
|
||||
let two = N::one() + N::one();
|
||||
@@ -66,7 +66,7 @@ pub fn is_build_required<N>(cht_size: N, block_num: N) -> Option<N>
|
||||
/// Returns Some(max_cht_number) if CHT has ever been built given maximal canonical block number.
|
||||
pub fn max_cht_number<N>(cht_size: N, max_canonical_block: N) -> Option<N>
|
||||
where
|
||||
N: Clone + SimpleArithmetic,
|
||||
N: Clone + AtLeast32Bit,
|
||||
{
|
||||
let max_cht_number = block_to_cht_number(cht_size, max_canonical_block)?;
|
||||
let two = N::one() + N::one();
|
||||
@@ -291,18 +291,18 @@ fn build_pairs<Header, I>(
|
||||
/// More generally: CHT N includes block (1 + N*SIZE)...((N+1)*SIZE).
|
||||
/// 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: N, cht_num: N) -> N {
|
||||
pub fn start_number<N: AtLeast32Bit>(cht_size: N, cht_num: N) -> N {
|
||||
(cht_num * cht_size) + N::one()
|
||||
}
|
||||
|
||||
/// Get the ending block of a given CHT.
|
||||
pub fn end_number<N: SimpleArithmetic>(cht_size: N, cht_num: N) -> N {
|
||||
pub fn end_number<N: AtLeast32Bit>(cht_size: N, cht_num: N) -> N {
|
||||
(cht_num + N::one()) * cht_size
|
||||
}
|
||||
|
||||
/// Convert a block number to a CHT number.
|
||||
/// Returns `None` for `block_num` == 0, `Some` otherwise.
|
||||
pub fn block_to_cht_number<N: SimpleArithmetic>(cht_size: N, block_num: N) -> Option<N> {
|
||||
pub fn block_to_cht_number<N: AtLeast32Bit>(cht_size: N, block_num: N) -> Option<N> {
|
||||
if block_num == N::zero() {
|
||||
None
|
||||
} else {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::cmp::Reverse;
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
use sp_runtime::traits::SimpleArithmetic;
|
||||
use sp_runtime::traits::AtLeast32Bit;
|
||||
use codec::{Encode, Decode};
|
||||
use sp_blockchain::{Error, Result};
|
||||
|
||||
@@ -65,7 +65,7 @@ pub struct LeafSet<H, N> {
|
||||
|
||||
impl<H, N> LeafSet<H, N> where
|
||||
H: Clone + PartialEq + Decode + Encode,
|
||||
N: std::fmt::Debug + Clone + SimpleArithmetic + Decode + Encode,
|
||||
N: std::fmt::Debug + Clone + AtLeast32Bit + Decode + Encode,
|
||||
{
|
||||
/// Construct a new, blank leaf set.
|
||||
pub fn new() -> Self {
|
||||
@@ -251,7 +251,7 @@ pub struct Undo<'a, H: 'a, N: 'a> {
|
||||
|
||||
impl<'a, H: 'a, N: 'a> Undo<'a, H, N> where
|
||||
H: Clone + PartialEq + Decode + Encode,
|
||||
N: std::fmt::Debug + Clone + SimpleArithmetic + Decode + Encode,
|
||||
N: std::fmt::Debug + Clone + AtLeast32Bit + Decode + Encode,
|
||||
{
|
||||
/// Undo an imported block by providing the displaced leaf.
|
||||
pub fn undo_import(&mut self, displaced: ImportDisplaced<H, N>) {
|
||||
|
||||
@@ -25,7 +25,7 @@ use codec::{Decode, Encode};
|
||||
use sp_core::{convert_hash, traits::CodeExecutor};
|
||||
use sp_runtime::traits::{
|
||||
Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor,
|
||||
SimpleArithmetic, CheckedConversion,
|
||||
AtLeast32Bit, CheckedConversion,
|
||||
};
|
||||
use sp_state_machine::{
|
||||
ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange,
|
||||
@@ -286,7 +286,7 @@ impl<E, Block, H, S> FetchChecker<Block> for LightDataChecker<E, H, Block, S>
|
||||
}
|
||||
|
||||
/// A view of BTreeMap<Number, Hash> as a changes trie roots storage.
|
||||
struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> {
|
||||
struct RootsStorage<'a, Number: AtLeast32Bit, Hash: 'a> {
|
||||
roots: (Number, &'a [Hash]),
|
||||
prev_roots: &'a BTreeMap<Number, Hash>,
|
||||
}
|
||||
@@ -294,7 +294,7 @@ struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> {
|
||||
impl<'a, H, Number, Hash> ChangesTrieRootsStorage<H, Number> for RootsStorage<'a, Number, Hash>
|
||||
where
|
||||
H: Hasher,
|
||||
Number: ::std::fmt::Display + ::std::hash::Hash + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static,
|
||||
Number: ::std::fmt::Display + ::std::hash::Hash + Clone + AtLeast32Bit + Encode + Decode + Send + Sync + 'static,
|
||||
Hash: 'a + Send + Sync + Clone + AsRef<[u8]>,
|
||||
{
|
||||
fn build_anchor(
|
||||
|
||||
@@ -34,7 +34,7 @@ use parking_lot::Mutex;
|
||||
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, NumberFor, SimpleArithmetic, Extrinsic},
|
||||
traits::{Block as BlockT, NumberFor, AtLeast32Bit, Extrinsic},
|
||||
};
|
||||
use sp_transaction_pool::{
|
||||
TransactionPool, PoolStatus, ImportNotificationStream,
|
||||
@@ -223,7 +223,7 @@ struct RevalidationAction {
|
||||
revalidate_amount: Option<usize>,
|
||||
}
|
||||
|
||||
impl<N: Clone + Copy + SimpleArithmetic> RevalidationStrategy<N> {
|
||||
impl<N: Clone + Copy + AtLeast32Bit> RevalidationStrategy<N> {
|
||||
pub fn clear(&mut self) {
|
||||
if let Self::Light(status) = self {
|
||||
status.clear()
|
||||
@@ -255,7 +255,7 @@ impl<N: Clone + Copy + SimpleArithmetic> RevalidationStrategy<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Copy + SimpleArithmetic> RevalidationStatus<N> {
|
||||
impl<N: Clone + Copy + AtLeast32Bit> RevalidationStatus<N> {
|
||||
/// Called when revalidation is completed.
|
||||
pub fn clear(&mut self) {
|
||||
*self = Self::NotScheduled;
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure};
|
||||
use sp_runtime::traits::{Member, SimpleArithmetic, Zero, StaticLookup};
|
||||
use sp_runtime::traits::{Member, AtLeast32Bit, Zero, StaticLookup};
|
||||
use frame_system::{self as system, ensure_signed};
|
||||
use sp_runtime::traits::One;
|
||||
|
||||
@@ -143,10 +143,10 @@ pub trait Trait: frame_system::Trait {
|
||||
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
|
||||
|
||||
/// The units in which we record balances.
|
||||
type Balance: Member + Parameter + SimpleArithmetic + Default + Copy;
|
||||
type Balance: Member + Parameter + AtLeast32Bit + Default + Copy;
|
||||
|
||||
/// The arithmetic type of asset identifier.
|
||||
type AssetId: Parameter + SimpleArithmetic + Default + Copy;
|
||||
type AssetId: Parameter + AtLeast32Bit + Default + Copy;
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
|
||||
@@ -25,7 +25,7 @@ pub use pallet_timestamp;
|
||||
use sp_std::{result, prelude::*};
|
||||
use frame_support::{decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}};
|
||||
use sp_timestamp::OnTimestampSet;
|
||||
use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill};
|
||||
use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill, PerThing};
|
||||
use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash};
|
||||
use sp_staking::{
|
||||
SessionIndex,
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use super::{Trait, Module, GenesisConfig};
|
||||
use sp_consensus_babe::AuthorityId;
|
||||
use sp_runtime::{
|
||||
traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, impl_opaque_keys,
|
||||
traits::IdentityLookup, Perbill, PerThing, testing::{Header, UintAuthorityId}, impl_opaque_keys,
|
||||
};
|
||||
use sp_version::RuntimeVersion;
|
||||
use frame_support::{impl_outer_origin, parameter_types, weights::Weight};
|
||||
|
||||
@@ -169,7 +169,7 @@ use frame_support::{
|
||||
use sp_runtime::{
|
||||
RuntimeDebug, DispatchResult, DispatchError,
|
||||
traits::{
|
||||
Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub,
|
||||
Zero, AtLeast32Bit, StaticLookup, Member, CheckedAdd, CheckedSub,
|
||||
MaybeSerializeDeserialize, Saturating, Bounded,
|
||||
},
|
||||
};
|
||||
@@ -180,7 +180,7 @@ pub use self::imbalances::{PositiveImbalance, NegativeImbalance};
|
||||
|
||||
pub trait Subtrait<I: Instance = DefaultInstance>: frame_system::Trait {
|
||||
/// The balance of an account.
|
||||
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy +
|
||||
type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy +
|
||||
MaybeSerializeDeserialize + Debug;
|
||||
|
||||
/// A function that is invoked when the free-balance and the reserved-balance has fallen below
|
||||
@@ -202,7 +202,7 @@ pub trait Subtrait<I: Instance = DefaultInstance>: frame_system::Trait {
|
||||
|
||||
pub trait Trait<I: Instance = DefaultInstance>: frame_system::Trait {
|
||||
/// The balance of an account.
|
||||
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy +
|
||||
type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy +
|
||||
MaybeSerializeDeserialize + Debug;
|
||||
|
||||
/// A function that is invoked when the free-balance and the reserved-balance has fallen below
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf};
|
||||
use sp_std::convert::TryFrom;
|
||||
use sp_runtime::traits::{
|
||||
CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto,
|
||||
CheckedMul, Zero, SaturatedConversion, AtLeast32Bit, UniqueSaturatedInto,
|
||||
};
|
||||
use frame_support::{
|
||||
traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReason}, StorageValue,
|
||||
@@ -248,7 +248,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<Balance>(gas_price: Balance, balance: Balance) -> Gas
|
||||
where Balance: SimpleArithmetic
|
||||
where Balance: AtLeast32Bit
|
||||
{
|
||||
(balance / gas_price).saturated_into::<Gas>()
|
||||
}
|
||||
|
||||
@@ -83,7 +83,10 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use sp_std::prelude::*;
|
||||
use sp_runtime::{print, DispatchResult, DispatchError, traits::{Zero, StaticLookup, Convert}};
|
||||
use sp_runtime::{
|
||||
print, DispatchResult, DispatchError, Perbill,
|
||||
traits::{Zero, StaticLookup, Convert},
|
||||
};
|
||||
use frame_support::{
|
||||
decl_storage, decl_event, ensure, decl_module, decl_error, weights::SimpleDispatchInfo,
|
||||
traits::{
|
||||
@@ -637,7 +640,7 @@ impl<T: Trait> Module<T> {
|
||||
let voters_and_votes = <VotesOf<T>>::enumerate()
|
||||
.map(|(v, i)| (v, i))
|
||||
.collect::<Vec<(T::AccountId, Vec<T::AccountId>)>>();
|
||||
let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote>(
|
||||
let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote, Perbill>(
|
||||
num_to_elect,
|
||||
0,
|
||||
candidates,
|
||||
@@ -664,7 +667,7 @@ impl<T: Trait> Module<T> {
|
||||
.filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } )
|
||||
.collect::<Vec<T::AccountId>>();
|
||||
|
||||
let support_map = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote>(
|
||||
let support_map = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote, Perbill>(
|
||||
&new_set,
|
||||
&phragmen_result.assignments,
|
||||
Self::locked_stake_of,
|
||||
|
||||
@@ -651,7 +651,8 @@ mod tests {
|
||||
// The testing primitives are very useful for avoiding having to work with signatures
|
||||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required.
|
||||
use sp_runtime::{
|
||||
Perbill, testing::Header,
|
||||
Perbill,
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup},
|
||||
};
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ use codec::{Decode, Encode, HasCompact, Input, Output, Error as CodecError};
|
||||
|
||||
use sp_runtime::{RuntimeDebug, DispatchResult, DispatchError};
|
||||
use sp_runtime::traits::{
|
||||
CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic,
|
||||
CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, AtLeast32Bit,
|
||||
Zero, Bounded,
|
||||
};
|
||||
|
||||
@@ -180,24 +180,24 @@ pub use self::imbalances::{NegativeImbalance, PositiveImbalance};
|
||||
pub trait Trait: frame_system::Trait {
|
||||
type Balance: Parameter
|
||||
+ Member
|
||||
+ SimpleArithmetic
|
||||
+ AtLeast32Bit
|
||||
+ Default
|
||||
+ Copy
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug;
|
||||
type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy;
|
||||
type AssetId: Parameter + Member + AtLeast32Bit + Default + Copy;
|
||||
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
|
||||
}
|
||||
|
||||
pub trait Subtrait: frame_system::Trait {
|
||||
type Balance: Parameter
|
||||
+ Member
|
||||
+ SimpleArithmetic
|
||||
+ AtLeast32Bit
|
||||
+ Default
|
||||
+ Copy
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug;
|
||||
type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy;
|
||||
type AssetId: Parameter + Member + AtLeast32Bit + Default + Copy;
|
||||
}
|
||||
|
||||
impl<T: Trait> Subtrait for T {
|
||||
|
||||
@@ -34,7 +34,7 @@ use sp_std::prelude::*;
|
||||
use codec::{self as codec, Encode, Decode};
|
||||
use frame_support::{decl_event, decl_storage, decl_module, decl_error, storage};
|
||||
use sp_runtime::{
|
||||
DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill,
|
||||
DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, PerThing,
|
||||
};
|
||||
use sp_staking::{
|
||||
SessionIndex,
|
||||
|
||||
@@ -79,7 +79,7 @@ use pallet_session::historical::IdentificationTuple;
|
||||
use sp_runtime::{
|
||||
offchain::storage::StorageValueRef,
|
||||
RuntimeDebug,
|
||||
traits::{Convert, Member, Saturating, SimpleArithmetic}, Perbill,
|
||||
traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, PerThing,
|
||||
transaction_validity::{
|
||||
TransactionValidity, ValidTransaction, InvalidTransaction,
|
||||
TransactionPriority,
|
||||
@@ -151,7 +151,7 @@ struct HeartbeatStatus<BlockNumber> {
|
||||
pub sent_at: BlockNumber,
|
||||
}
|
||||
|
||||
impl<BlockNumber: PartialEq + SimpleArithmetic + Copy> HeartbeatStatus<BlockNumber> {
|
||||
impl<BlockNumber: PartialEq + AtLeast32Bit + Copy> HeartbeatStatus<BlockNumber> {
|
||||
/// Returns true if heartbeat has been recently sent.
|
||||
///
|
||||
/// Parameters:
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
use sp_std::{prelude::*, marker::PhantomData, convert::TryInto};
|
||||
use codec::{Encode, Codec};
|
||||
use frame_support::{Parameter, decl_module, decl_event, decl_storage};
|
||||
use sp_runtime::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError};
|
||||
use sp_runtime::traits::{One, AtLeast32Bit, StaticLookup, Member, LookupError};
|
||||
use frame_system::{IsDeadAccount, OnNewAccount};
|
||||
|
||||
use self::address::Address as RawAddress;
|
||||
@@ -59,7 +59,7 @@ impl<AccountId: Encode, AccountIndex: From<u32>>
|
||||
pub trait Trait: frame_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 + Copy;
|
||||
type AccountIndex: Parameter + Member + Codec + Default + AtLeast32Bit + Copy;
|
||||
|
||||
/// Whether an account is dead or not.
|
||||
type IsDeadAccount: IsDeadAccount<Self::AccountId>;
|
||||
|
||||
@@ -154,7 +154,9 @@ mod tests {
|
||||
use super::*;
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header,
|
||||
Perbill,
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup},
|
||||
};
|
||||
use frame_support::{impl_outer_origin, parameter_types, weights::Weight, traits::Randomness};
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ use frame_support::{
|
||||
};
|
||||
use frame_system::{self as system, ensure_root, ensure_signed};
|
||||
use sp_runtime::{
|
||||
traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDeserialize, Zero, StaticLookup},
|
||||
traits::{EnsureOrigin, AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup},
|
||||
};
|
||||
|
||||
type BalanceOf<T, I> = <<T as Trait<I>>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
|
||||
@@ -121,7 +121,7 @@ pub trait Trait<I=DefaultInstance>: frame_system::Trait {
|
||||
|
||||
/// The score attributed to a member or candidate.
|
||||
type Score:
|
||||
SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug;
|
||||
AtLeast32Bit + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug;
|
||||
|
||||
/// The overarching event type.
|
||||
type Event: From<Event<Self, I>> + Into<<Self as frame_system::Trait>::Event>;
|
||||
|
||||
@@ -21,8 +21,9 @@ use std::cell::RefCell;
|
||||
use frame_support::{impl_outer_origin, parameter_types, weights::Weight};
|
||||
use sp_core::{crypto::key_types::DUMMY, H256};
|
||||
use sp_runtime::{
|
||||
Perbill, impl_opaque_keys, traits::{BlakeTwo256, IdentityLookup, ConvertInto},
|
||||
testing::{Header, UintAuthorityId}
|
||||
Perbill, impl_opaque_keys,
|
||||
traits::{BlakeTwo256, IdentityLookup, ConvertInto},
|
||||
testing::{Header, UintAuthorityId},
|
||||
};
|
||||
use sp_staking::SessionIndex;
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ use sp_core::H256;
|
||||
// The testing primitives are very useful for avoiding having to work with signatures
|
||||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
|
||||
use sp_runtime::{
|
||||
Perbill, traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize}, testing::Header,
|
||||
Perbill,
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize},
|
||||
};
|
||||
use frame_system::EnsureSignedBy;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//! The staking rate in NPoS is the total amount of tokens staked by nominators and validators,
|
||||
//! divided by the total token supply.
|
||||
|
||||
use sp_runtime::{Perbill, traits::SimpleArithmetic, curve::PiecewiseLinear};
|
||||
use sp_runtime::{Perbill, PerThing, traits::AtLeast32Bit, curve::PiecewiseLinear};
|
||||
|
||||
/// The total payout to all validators (and their nominators) per era.
|
||||
///
|
||||
@@ -32,7 +32,7 @@ pub fn compute_total_payout<N>(
|
||||
npos_token_staked: N,
|
||||
total_tokens: N,
|
||||
era_duration: u64
|
||||
) -> (N, N) where N: SimpleArithmetic + Clone {
|
||||
) -> (N, N) where N: AtLeast32Bit + Clone {
|
||||
// Milliseconds per year for the Julian year (365.25 days).
|
||||
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
|
||||
|
||||
|
||||
@@ -267,12 +267,11 @@ use frame_support::{
|
||||
};
|
||||
use pallet_session::historical::SessionManager;
|
||||
use sp_runtime::{
|
||||
Perbill,
|
||||
RuntimeDebug,
|
||||
Perbill, PerThing, RuntimeDebug,
|
||||
curve::PiecewiseLinear,
|
||||
traits::{
|
||||
Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SaturatedConversion,
|
||||
SimpleArithmetic, EnsureOrigin,
|
||||
AtLeast32Bit, EnsureOrigin,
|
||||
}
|
||||
};
|
||||
use sp_staking::{
|
||||
@@ -396,7 +395,7 @@ pub struct StakingLedger<AccountId, Balance: HasCompact> {
|
||||
|
||||
impl<
|
||||
AccountId,
|
||||
Balance: HasCompact + Copy + Saturating + SimpleArithmetic,
|
||||
Balance: HasCompact + Copy + Saturating + AtLeast32Bit,
|
||||
> StakingLedger<AccountId, Balance> {
|
||||
/// Remove entries from `unlocking` that are sufficiently old and reduce the
|
||||
/// total by the sum of their balances.
|
||||
@@ -440,7 +439,7 @@ impl<
|
||||
}
|
||||
|
||||
impl<AccountId, Balance> StakingLedger<AccountId, Balance> where
|
||||
Balance: SimpleArithmetic + Saturating + Copy,
|
||||
Balance: AtLeast32Bit + Saturating + Copy,
|
||||
{
|
||||
/// Slash the validator for a given amount of balance. This can grow the value
|
||||
/// of the slash in the case that the validator has less than `minimum_balance`
|
||||
@@ -1503,7 +1502,7 @@ impl<T: Trait> Module<T> {
|
||||
});
|
||||
all_nominators.extend(nominator_votes);
|
||||
|
||||
let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote>(
|
||||
let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote, Perbill>(
|
||||
Self::validator_count() as usize,
|
||||
Self::minimum_validator_count().max(1) as usize,
|
||||
all_validators,
|
||||
@@ -1520,7 +1519,7 @@ impl<T: Trait> Module<T> {
|
||||
let to_balance = |e: ExtendedBalance|
|
||||
<T::CurrencyToVote as Convert<ExtendedBalance, BalanceOf<T>>>::convert(e);
|
||||
|
||||
let supports = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote>(
|
||||
let supports = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote, Perbill>(
|
||||
&elected_stashes,
|
||||
&assignments,
|
||||
Self::slashable_balance_of,
|
||||
|
||||
@@ -52,7 +52,7 @@ use super::{
|
||||
EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface,
|
||||
NegativeImbalanceOf, UnappliedSlash,
|
||||
};
|
||||
use sp_runtime::traits::{Zero, Saturating};
|
||||
use sp_runtime::{traits::{Zero, Saturating}, PerThing};
|
||||
use frame_support::{
|
||||
StorageMap, StorageDoubleMap,
|
||||
traits::{Currency, OnUnbalanced, Imbalance},
|
||||
|
||||
@@ -24,7 +24,7 @@ use sp_core::u32_trait::Value as U32;
|
||||
use sp_runtime::{
|
||||
RuntimeDebug,
|
||||
ConsensusEngineId, DispatchResult, DispatchError,
|
||||
traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating, TrailingZeroInput},
|
||||
traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput},
|
||||
};
|
||||
|
||||
use crate::dispatch::Parameter;
|
||||
@@ -267,7 +267,7 @@ pub enum SignedImbalance<B, P: Imbalance<B>>{
|
||||
impl<
|
||||
P: Imbalance<B, Opposite=N>,
|
||||
N: Imbalance<B, Opposite=P>,
|
||||
B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default,
|
||||
B: AtLeast32Bit + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default,
|
||||
> SignedImbalance<B, P> {
|
||||
pub fn zero() -> Self {
|
||||
SignedImbalance::Positive(P::zero())
|
||||
@@ -330,7 +330,7 @@ impl<
|
||||
/// Abstraction over a fungible assets system.
|
||||
pub trait Currency<AccountId> {
|
||||
/// The balance of an account.
|
||||
type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default;
|
||||
type Balance: AtLeast32Bit + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default;
|
||||
|
||||
/// The opaque token type for an imbalance. This is returned by unbalanced operations
|
||||
/// and must be dealt with. It may be dropped but cannot be cloned.
|
||||
@@ -659,7 +659,7 @@ bitmask! {
|
||||
}
|
||||
|
||||
pub trait Time {
|
||||
type Moment: SimpleArithmetic + Parameter + Default + Copy;
|
||||
type Moment: AtLeast32Bit + Parameter + Default + Copy;
|
||||
|
||||
fn now() -> Self::Moment;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box};
|
||||
use frame_system as system;
|
||||
use frame_support::{decl_module, decl_event, impl_outer_origin, impl_outer_event, weights::Weight};
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header};
|
||||
use sp_runtime::{Perbill, PerThing, traits::{BlakeTwo256, IdentityLookup}, testing::Header};
|
||||
|
||||
mod module {
|
||||
use super::*;
|
||||
|
||||
@@ -97,14 +97,14 @@ use sp_std::marker::PhantomData;
|
||||
use sp_std::fmt::Debug;
|
||||
use sp_version::RuntimeVersion;
|
||||
use sp_runtime::{
|
||||
RuntimeDebug,
|
||||
generic::{self, Era}, Perbill, DispatchOutcome, DispatchError,
|
||||
RuntimeDebug, Perbill, DispatchOutcome, DispatchError,
|
||||
generic::{self, Era},
|
||||
transaction_validity::{
|
||||
ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError,
|
||||
InvalidTransaction, TransactionValidity,
|
||||
},
|
||||
traits::{
|
||||
self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError,
|
||||
self, CheckEqual, AtLeast32Bit, Zero, SignedExtension, Lookup, LookupError,
|
||||
SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, BadOrigin, SaturatedConversion,
|
||||
MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded,
|
||||
},
|
||||
@@ -165,12 +165,12 @@ pub trait Trait: 'static + Eq + Clone {
|
||||
/// Account index (aka nonce) type. This stores the number of previous transactions associated
|
||||
/// with a sender account.
|
||||
type Index:
|
||||
Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic
|
||||
Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit
|
||||
+ Copy;
|
||||
|
||||
/// The block number type used by the runtime.
|
||||
type BlockNumber:
|
||||
Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic
|
||||
Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + AtLeast32Bit
|
||||
+ Default + Bounded + Copy + sp_std::hash::Hash + sp_std::str::FromStr + MaybeMallocSizeOf;
|
||||
|
||||
/// The output of the `Hashing` function.
|
||||
@@ -898,7 +898,7 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
|
||||
/// a portion.
|
||||
fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill {
|
||||
match class {
|
||||
DispatchClass::Operational => Perbill::one(),
|
||||
DispatchClass::Operational => <Perbill as sp_runtime::PerThing>::one(),
|
||||
DispatchClass::Normal => T::AvailableBlockRatio::get(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ use frame_support::traits::{Time, Get};
|
||||
use sp_runtime::{
|
||||
RuntimeString,
|
||||
traits::{
|
||||
SimpleArithmetic, Zero, SaturatedConversion, Scale
|
||||
AtLeast32Bit, Zero, SaturatedConversion, Scale
|
||||
}
|
||||
};
|
||||
use frame_support::weights::SimpleDispatchInfo;
|
||||
@@ -112,7 +112,7 @@ use sp_timestamp::{
|
||||
/// The module configuration trait
|
||||
pub trait Trait: frame_system::Trait {
|
||||
/// Type used for expressing timestamp.
|
||||
type Moment: Parameter + Default + SimpleArithmetic
|
||||
type Moment: Parameter + Default + AtLeast32Bit
|
||||
+ Scale<Self::BlockNumber, Output = Self::Moment> + Copy;
|
||||
|
||||
/// Something which can be notified when the timestamp is set. Set this to `()` if not needed.
|
||||
|
||||
@@ -590,7 +590,7 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove any non-members of `Tippers` from a `tips` vectr. `O(T)`.
|
||||
/// Remove any non-members of `Tippers` from a `tips` vector. `O(T)`.
|
||||
fn retain_active_tips(tips: &mut Vec<(T::AccountId, BalanceOf<T>)>) {
|
||||
let members = T::Tippers::sorted_members();
|
||||
let mut members_iter = members.iter();
|
||||
@@ -724,7 +724,9 @@ mod tests {
|
||||
use frame_support::traits::Contains;
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin}, testing::Header, Perbill
|
||||
Perbill,
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin},
|
||||
};
|
||||
|
||||
impl_outer_origin! {
|
||||
|
||||
@@ -50,7 +50,7 @@ use sp_std::prelude::*;
|
||||
use sp_std::fmt::Debug;
|
||||
use codec::{Encode, Decode};
|
||||
use sp_runtime::{DispatchResult, RuntimeDebug, traits::{
|
||||
StaticLookup, Zero, SimpleArithmetic, MaybeSerializeDeserialize, Saturating, Convert
|
||||
StaticLookup, Zero, AtLeast32Bit, MaybeSerializeDeserialize, Saturating, Convert
|
||||
}};
|
||||
use frame_support::{decl_module, decl_event, decl_storage, decl_error};
|
||||
use frame_support::traits::{
|
||||
@@ -85,8 +85,8 @@ pub struct VestingInfo<Balance, BlockNumber> {
|
||||
}
|
||||
|
||||
impl<
|
||||
Balance: SimpleArithmetic + Copy,
|
||||
BlockNumber: SimpleArithmetic + Copy,
|
||||
Balance: AtLeast32Bit + Copy,
|
||||
BlockNumber: AtLeast32Bit + Copy,
|
||||
> VestingInfo<Balance, BlockNumber> {
|
||||
/// Amount locked at block `n`.
|
||||
pub fn locked_at<
|
||||
@@ -298,7 +298,9 @@ mod tests {
|
||||
// The testing primitives are very useful for avoiding having to work with signatures
|
||||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required.
|
||||
use sp_runtime::{
|
||||
Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup, Identity, OnInitialize},
|
||||
Perbill,
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, IdentityLookup, Identity, OnInitialize},
|
||||
};
|
||||
use sp_storage::Storage;
|
||||
|
||||
|
||||
@@ -40,5 +40,5 @@ mod fixed64;
|
||||
mod rational128;
|
||||
|
||||
pub use fixed64::Fixed64;
|
||||
pub use per_things::{Percent, Permill, Perbill, Perquintill};
|
||||
pub use per_things::{PerThing, Percent, Permill, Perbill, Perquintill};
|
||||
pub use rational128::Rational128;
|
||||
|
||||
@@ -19,34 +19,148 @@ use serde::{Serialize, Deserialize};
|
||||
|
||||
use sp_std::{ops, prelude::*, convert::TryInto};
|
||||
use codec::{Encode, Decode, CompactAs};
|
||||
use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating};
|
||||
use crate::traits::{
|
||||
SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic,
|
||||
};
|
||||
use sp_debug_derive::RuntimeDebug;
|
||||
|
||||
/// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per
|
||||
/// `X`_.
|
||||
pub trait PerThing: Sized + Saturating + Copy {
|
||||
/// The data type used to build this per-thingy.
|
||||
type Inner: BaseArithmetic + Copy;
|
||||
|
||||
/// accuracy of this type
|
||||
const ACCURACY: Self::Inner;
|
||||
|
||||
/// NoThing
|
||||
fn zero() -> Self;
|
||||
|
||||
/// `true` if this is nothing.
|
||||
fn is_zero(&self) -> bool;
|
||||
|
||||
/// Everything.
|
||||
fn one() -> Self;
|
||||
|
||||
/// Consume self and deconstruct into a raw numeric type.
|
||||
fn deconstruct(self) -> Self::Inner;
|
||||
|
||||
/// From an explicitly defined number of parts per maximum of the type.
|
||||
fn from_parts(parts: Self::Inner) -> Self;
|
||||
|
||||
/// Converts a percent into `Self`. Equal to `x / 100`.
|
||||
fn from_percent(x: Self::Inner) -> Self;
|
||||
|
||||
/// Return the product of multiplication of this value by itself.
|
||||
fn square(self) -> Self;
|
||||
|
||||
/// Converts a fraction into `Self`.
|
||||
#[cfg(feature = "std")]
|
||||
fn from_fraction(x: f64) -> Self;
|
||||
|
||||
/// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow.
|
||||
///
|
||||
/// The computation of this approximation is performed in the generic type `N`. Given
|
||||
/// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for
|
||||
/// perbill), this can only work if `N == M` or `N: From<M> + TryInto<M>`.
|
||||
fn from_rational_approximation<N>(p: N, q: N) -> Self
|
||||
where N: Clone + Ord + From<Self::Inner> + TryInto<Self::Inner> + ops::Div<N, Output=N>;
|
||||
}
|
||||
|
||||
macro_rules! implement_per_thing {
|
||||
($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => {
|
||||
/// A fixed point representation of a number between in the range [0, 1].
|
||||
///
|
||||
#[doc = $title]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)]
|
||||
#[derive(Encode, Decode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)]
|
||||
pub struct $name($type);
|
||||
|
||||
impl $name {
|
||||
impl PerThing for $name {
|
||||
type Inner = $type;
|
||||
|
||||
/// The accuracy of this type.
|
||||
const ACCURACY: Self::Inner = $max;
|
||||
|
||||
/// Nothing.
|
||||
pub fn zero() -> Self { Self(0) }
|
||||
fn zero() -> Self { Self(0) }
|
||||
|
||||
/// `true` if this is nothing.
|
||||
pub fn is_zero(&self) -> bool { self.0 == 0 }
|
||||
fn is_zero(&self) -> bool { self.0 == 0 }
|
||||
|
||||
/// Everything.
|
||||
pub fn one() -> Self { Self($max) }
|
||||
fn one() -> Self { Self($max) }
|
||||
|
||||
/// Consume self and deconstruct into a raw numeric type.
|
||||
pub fn deconstruct(self) -> $type { self.0 }
|
||||
fn deconstruct(self) -> Self::Inner { self.0 }
|
||||
|
||||
/// Return the scale at which this per-thing is working.
|
||||
pub const fn accuracy() -> $type { $max }
|
||||
/// From an explicitly defined number of parts per maximum of the type.
|
||||
fn from_parts(parts: Self::Inner) -> Self {
|
||||
Self([parts, $max][(parts > $max) as usize])
|
||||
}
|
||||
|
||||
/// Converts a percent into `Self`. Equal to `x / 100`.
|
||||
fn from_percent(x: Self::Inner) -> Self {
|
||||
Self([x, 100][(x > 100) as usize] * ($max / 100))
|
||||
}
|
||||
|
||||
/// Return the product of multiplication of this value by itself.
|
||||
fn square(self) -> Self {
|
||||
// both can be safely casted and multiplied.
|
||||
let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type;
|
||||
let q: $upper_type = <$upper_type>::from($max) * <$upper_type>::from($max);
|
||||
Self::from_rational_approximation(p, q)
|
||||
}
|
||||
|
||||
/// Converts a fraction into `Self`.
|
||||
#[cfg(feature = "std")]
|
||||
fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as Self::Inner) }
|
||||
|
||||
/// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow.
|
||||
///
|
||||
/// The computation of this approximation is performed in the generic type `N`. Given
|
||||
/// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for
|
||||
/// perbill), this can only work if `N == M` or `N: From<M> + TryInto<M>`.
|
||||
fn from_rational_approximation<N>(p: N, q: N) -> Self
|
||||
where N: Clone + Ord + From<Self::Inner> + TryInto<Self::Inner> + ops::Div<N, Output=N>
|
||||
{
|
||||
// q cannot be zero.
|
||||
let q = q.max((1 as Self::Inner).into());
|
||||
// p should not be bigger than q.
|
||||
let p = p.min(q.clone());
|
||||
|
||||
let factor = (q.clone() / $max.into()).max((1 as Self::Inner).into());
|
||||
|
||||
// q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow.
|
||||
// this implies that Self::Inner must be able to fit 2 * $max.
|
||||
let q_reduce: Self::Inner = (q / factor.clone())
|
||||
.try_into()
|
||||
.map_err(|_| "Failed to convert")
|
||||
.expect(
|
||||
"q / (q/$max) < (2 * $max). Macro prevents any type being created that \
|
||||
does not satisfy this; qed"
|
||||
);
|
||||
let p_reduce: Self::Inner = (p / factor.clone())
|
||||
.try_into()
|
||||
.map_err(|_| "Failed to convert")
|
||||
.expect(
|
||||
"q / (q/$max) < (2 * $max). Macro prevents any type being created that \
|
||||
does not satisfy this; qed"
|
||||
);
|
||||
|
||||
// `p_reduced` and `q_reduced` are withing Self::Inner. Mul by another $max will
|
||||
// always fit in $upper_type. This is guaranteed by the macro tests.
|
||||
let part =
|
||||
p_reduce as $upper_type
|
||||
* <$upper_type>::from($max)
|
||||
/ q_reduce as $upper_type;
|
||||
|
||||
$name(part as Self::Inner)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement const functions
|
||||
impl $name {
|
||||
/// From an explicitly defined number of parts per maximum of the type.
|
||||
///
|
||||
/// This can be called at compile time.
|
||||
@@ -61,58 +175,12 @@ macro_rules! implement_per_thing {
|
||||
Self([x, 100][(x > 100) as usize] * ($max / 100))
|
||||
}
|
||||
|
||||
/// Return the product of multiplication of this value by itself.
|
||||
pub fn square(self) -> Self {
|
||||
// both can be safely casted and multiplied.
|
||||
let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type;
|
||||
let q: $upper_type = <$upper_type>::from($max) * <$upper_type>::from($max);
|
||||
Self::from_rational_approximation(p, q)
|
||||
}
|
||||
|
||||
/// Converts a fraction into `Self`.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as $type) }
|
||||
|
||||
/// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow.
|
||||
/// Everything.
|
||||
///
|
||||
/// The computation of this approximation is performed in the generic type `N`. Given
|
||||
/// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for
|
||||
/// perbill), this can only work if `N == M` or `N: From<M> + TryInto<M>`.
|
||||
pub fn from_rational_approximation<N>(p: N, q: N) -> Self
|
||||
where N: Clone + Ord + From<$type> + TryInto<$type> + ops::Div<N, Output=N>
|
||||
{
|
||||
// q cannot be zero.
|
||||
let q = q.max((1 as $type).into());
|
||||
// p should not be bigger than q.
|
||||
let p = p.min(q.clone());
|
||||
|
||||
let factor = (q.clone() / $max.into()).max((1 as $type).into());
|
||||
|
||||
// q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow.
|
||||
// this implies that $type must be able to fit 2 * $max.
|
||||
let q_reduce: $type = (q / factor.clone())
|
||||
.try_into()
|
||||
.map_err(|_| "Failed to convert")
|
||||
.expect(
|
||||
"q / (q/$max) < (2 * $max). Macro prevents any type being created that \
|
||||
does not satisfy this; qed"
|
||||
);
|
||||
let p_reduce: $type = (p / factor.clone())
|
||||
.try_into()
|
||||
.map_err(|_| "Failed to convert")
|
||||
.expect(
|
||||
"q / (q/$max) < (2 * $max). Macro prevents any type being created that \
|
||||
does not satisfy this; qed"
|
||||
);
|
||||
|
||||
// `p_reduced` and `q_reduced` are withing $type. Mul by another $max will always
|
||||
// fit in $upper_type. This is guaranteed by the macro tests.
|
||||
let part =
|
||||
p_reduce as $upper_type
|
||||
* <$upper_type>::from($max)
|
||||
/ q_reduce as $upper_type;
|
||||
|
||||
$name(part as $type)
|
||||
/// To avoid having to import `PerThing` when one needs to be used in test mocks.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn one() -> Self {
|
||||
<Self as PerThing>::one()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +258,7 @@ macro_rules! implement_per_thing {
|
||||
#[cfg(test)]
|
||||
mod $test_mod {
|
||||
use codec::{Encode, Decode};
|
||||
use super::{$name, Saturating, RuntimeDebug};
|
||||
use super::{$name, Saturating, RuntimeDebug, PerThing};
|
||||
use crate::traits::Zero;
|
||||
|
||||
|
||||
@@ -248,7 +316,7 @@ macro_rules! implement_per_thing {
|
||||
// some really basic stuff
|
||||
assert_eq!($name::zero(), $name::from_parts(Zero::zero()));
|
||||
assert_eq!($name::one(), $name::from_parts($max));
|
||||
assert_eq!($name::accuracy(), $max);
|
||||
assert_eq!($name::ACCURACY, $max);
|
||||
assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero()));
|
||||
assert_eq!($name::from_percent(10), $name::from_parts($max / 10));
|
||||
assert_eq!($name::from_percent(100), $name::from_parts($max));
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Primitives for the runtime modules.
|
||||
//! Primitive traits for the runtime arithmetic.
|
||||
|
||||
use sp_std::{self, convert::{TryFrom, TryInto}};
|
||||
use codec::HasCompact;
|
||||
@@ -28,44 +28,55 @@ use sp_std::ops::{
|
||||
RemAssign, Shl, Shr
|
||||
};
|
||||
|
||||
/// A meta trait for arithmetic type operations, regardless of any limitation on size.
|
||||
pub trait BaseArithmetic:
|
||||
From<u8> +
|
||||
Zero + One + IntegerSquareRoot +
|
||||
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 + Sized +
|
||||
TryFrom<u8> + TryInto<u8> + TryFrom<u16> + TryInto<u16> + TryFrom<u32> + TryInto<u32> +
|
||||
TryFrom<u64> + TryInto<u64> + TryFrom<u128> + TryInto<u128> + TryFrom<usize> + TryInto<usize> +
|
||||
UniqueSaturatedFrom<u8> + UniqueSaturatedInto<u8> +
|
||||
UniqueSaturatedFrom<u16> + UniqueSaturatedInto<u16> +
|
||||
UniqueSaturatedFrom<u32> + UniqueSaturatedInto<u32> +
|
||||
UniqueSaturatedFrom<u64> + UniqueSaturatedInto<u64> +
|
||||
UniqueSaturatedFrom<u128> + UniqueSaturatedInto<u128>
|
||||
{}
|
||||
|
||||
impl<T:
|
||||
From<u8> +
|
||||
Zero + One + IntegerSquareRoot +
|
||||
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 + Sized +
|
||||
TryFrom<u8> + TryInto<u8> + TryFrom<u16> + TryInto<u16> + TryFrom<u32> + TryInto<u32> +
|
||||
TryFrom<u64> + TryInto<u64> + TryFrom<u128> + TryInto<u128> + TryFrom<usize> + TryInto<usize> +
|
||||
UniqueSaturatedFrom<u8> + UniqueSaturatedInto<u8> +
|
||||
UniqueSaturatedFrom<u16> + UniqueSaturatedInto<u16> +
|
||||
UniqueSaturatedFrom<u32> + UniqueSaturatedInto<u32> +
|
||||
UniqueSaturatedFrom<u64> + UniqueSaturatedInto<u64> +
|
||||
UniqueSaturatedFrom<u128> + UniqueSaturatedInto<u128>
|
||||
> BaseArithmetic for T {}
|
||||
|
||||
/// 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 +
|
||||
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 + Sized
|
||||
{}
|
||||
impl<T:
|
||||
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 + Sized
|
||||
> SimpleArithmetic for T {}
|
||||
/// and smaller integers. All other conversions are fallible.
|
||||
pub trait AtLeast32Bit: BaseArithmetic + From<u16> + From<u32> {}
|
||||
|
||||
impl<T: BaseArithmetic + From<u16> + From<u32>> AtLeast32Bit 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.
|
||||
|
||||
@@ -33,10 +33,14 @@
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use sp_std::{prelude::*, collections::btree_map::BTreeMap};
|
||||
use sp_runtime::RuntimeDebug;
|
||||
use sp_runtime::{helpers_128bit::multiply_by_rational, Perbill, Rational128};
|
||||
use sp_runtime::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded};
|
||||
use sp_std::{prelude::*, collections::btree_map::BTreeMap, convert::TryFrom};
|
||||
use sp_runtime::{
|
||||
PerThing, Rational128, RuntimeDebug,
|
||||
helpers_128bit::multiply_by_rational,
|
||||
};
|
||||
use sp_runtime::traits::{
|
||||
Zero, Convert, Member, AtLeast32Bit, SaturatedConversion, Bounded, Saturating,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
@@ -93,21 +97,21 @@ pub struct Edge<AccountId> {
|
||||
candidate_index: usize,
|
||||
}
|
||||
|
||||
/// Means a particular `AccountId` was backed by `Perbill`th of a nominator's stake.
|
||||
pub type PhragmenAssignment<AccountId> = (AccountId, Perbill);
|
||||
/// Particular `AccountId` was backed by `T`-ratio of a nominator's stake.
|
||||
pub type PhragmenAssignment<AccountId, T> = (AccountId, T);
|
||||
|
||||
/// Means a particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake.
|
||||
/// Particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake.
|
||||
pub type PhragmenStakedAssignment<AccountId> = (AccountId, ExtendedBalance);
|
||||
|
||||
/// Final result of the phragmen election.
|
||||
#[derive(RuntimeDebug)]
|
||||
pub struct PhragmenResult<AccountId> {
|
||||
pub struct PhragmenResult<AccountId, T: PerThing> {
|
||||
/// Just winners zipped with their approval stake. Note that the approval stake is merely the
|
||||
/// sub of their received stake and could be used for very basic sorting and approval voting.
|
||||
pub winners: Vec<(AccountId, ExtendedBalance)>,
|
||||
/// Individual assignments. for each tuple, the first elements is a voter and the second
|
||||
/// is the list of candidates that it supports.
|
||||
pub assignments: Vec<(AccountId, Vec<PhragmenAssignment<AccountId>>)>
|
||||
pub assignments: Vec<(AccountId, Vec<PhragmenAssignment<AccountId, T>>)>
|
||||
}
|
||||
|
||||
/// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how
|
||||
@@ -145,23 +149,24 @@ pub type SupportMap<A> = BTreeMap<A, Support<A>>;
|
||||
/// responsibility of the caller to make sure only those candidates who have a sensible economic
|
||||
/// value are passed in. From the perspective of this function, a candidate can easily be among the
|
||||
/// winner with no backing stake.
|
||||
pub fn elect<AccountId, Balance, FS, C>(
|
||||
pub fn elect<AccountId, Balance, FS, C, R>(
|
||||
candidate_count: usize,
|
||||
minimum_candidate_count: usize,
|
||||
initial_candidates: Vec<AccountId>,
|
||||
initial_voters: Vec<(AccountId, Vec<AccountId>)>,
|
||||
stake_of: FS,
|
||||
) -> Option<PhragmenResult<AccountId>> where
|
||||
) -> Option<PhragmenResult<AccountId, R>> where
|
||||
AccountId: Default + Ord + Member,
|
||||
Balance: Default + Copy + SimpleArithmetic,
|
||||
Balance: Default + Copy + AtLeast32Bit,
|
||||
for<'r> FS: Fn(&'r AccountId) -> Balance,
|
||||
C: Convert<Balance, u64> + Convert<u128, Balance>,
|
||||
R: PerThing,
|
||||
{
|
||||
let to_votes = |b: Balance| <C as Convert<Balance, u64>>::convert(b) as ExtendedBalance;
|
||||
|
||||
// return structures
|
||||
let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>;
|
||||
let mut assigned: Vec<(AccountId, Vec<PhragmenAssignment<AccountId>>)>;
|
||||
let mut assigned: Vec<(AccountId, Vec<PhragmenAssignment<AccountId, R>>)>;
|
||||
|
||||
// used to cache and access candidates index.
|
||||
let mut c_idx_cache = BTreeMap::<AccountId, usize>::new();
|
||||
@@ -272,20 +277,29 @@ pub fn elect<AccountId, Balance, FS, C>(
|
||||
let mut assignment = (n.who.clone(), vec![]);
|
||||
for e in &mut n.edges {
|
||||
if elected_candidates.iter().position(|(ref c, _)| *c == e.who).is_some() {
|
||||
let per_bill_parts =
|
||||
let per_bill_parts: R::Inner =
|
||||
{
|
||||
if n.load == e.load {
|
||||
// Full support. No need to calculate.
|
||||
Perbill::accuracy().into()
|
||||
R::ACCURACY
|
||||
} else {
|
||||
if e.load.d() == n.load.d() {
|
||||
// return e.load / n.load.
|
||||
let desired_scale: u128 = Perbill::accuracy().into();
|
||||
multiply_by_rational(
|
||||
let desired_scale: u128 = R::ACCURACY.saturated_into();
|
||||
let parts = multiply_by_rational(
|
||||
desired_scale,
|
||||
e.load.n(),
|
||||
n.load.n(),
|
||||
).unwrap_or(Bounded::max_value())
|
||||
)
|
||||
// If result cannot fit in u128. Not much we can do about it.
|
||||
.unwrap_or(Bounded::max_value());
|
||||
|
||||
TryFrom::try_from(parts)
|
||||
// If the result cannot fit into R::Inner. Defensive only. This can
|
||||
// never happen. `desired_scale * e / n`, where `e / n < 1` always
|
||||
// yields a value smaller than `desired_scale`, which will fit into
|
||||
// R::Inner.
|
||||
.unwrap_or(Bounded::max_value())
|
||||
} else {
|
||||
// defensive only. Both edge and nominator loads are built from
|
||||
// scores, hence MUST have the same denominator.
|
||||
@@ -293,10 +307,7 @@ pub fn elect<AccountId, Balance, FS, C>(
|
||||
}
|
||||
}
|
||||
};
|
||||
// safer to .min() inside as well to argue as u32 is safe.
|
||||
let per_thing = Perbill::from_parts(
|
||||
per_bill_parts.min(Perbill::accuracy().into()) as u32
|
||||
);
|
||||
let per_thing = R::from_parts(per_bill_parts);
|
||||
assignment.1.push((e.who.clone(), per_thing));
|
||||
}
|
||||
}
|
||||
@@ -304,20 +315,19 @@ pub fn elect<AccountId, Balance, FS, C>(
|
||||
if assignment.1.len() > 0 {
|
||||
// To ensure an assertion indicating: no stake from the nominator going to waste,
|
||||
// we add a minimal post-processing to equally assign all of the leftover stake ratios.
|
||||
let vote_count = assignment.1.len() as u32;
|
||||
let vote_count: R::Inner = assignment.1.len().saturated_into();
|
||||
let len = assignment.1.len();
|
||||
let sum = assignment.1.iter()
|
||||
.map(|a| a.1.deconstruct())
|
||||
.sum::<u32>();
|
||||
let accuracy = Perbill::accuracy();
|
||||
let diff = accuracy.checked_sub(sum).unwrap_or(0);
|
||||
let mut sum: R::Inner = Zero::zero();
|
||||
assignment.1.iter().for_each(|a| sum = sum.saturating_add(a.1.deconstruct()));
|
||||
let accuracy = R::ACCURACY;
|
||||
let diff = accuracy.saturating_sub(sum);
|
||||
let diff_per_vote = (diff / vote_count).min(accuracy);
|
||||
|
||||
if diff_per_vote > 0 {
|
||||
if !diff_per_vote.is_zero() {
|
||||
for i in 0..len {
|
||||
let current_ratio = assignment.1[i % len].1;
|
||||
let next_ratio = current_ratio
|
||||
.saturating_add(Perbill::from_parts(diff_per_vote));
|
||||
.saturating_add(R::from_parts(diff_per_vote));
|
||||
assignment.1[i % len].1 = next_ratio;
|
||||
}
|
||||
}
|
||||
@@ -325,9 +335,9 @@ pub fn elect<AccountId, Balance, FS, C>(
|
||||
// `remainder` is set to be less than maximum votes of a nominator (currently 16).
|
||||
// safe to cast it to usize.
|
||||
let remainder = diff - diff_per_vote * vote_count;
|
||||
for i in 0..remainder as usize {
|
||||
for i in 0..remainder.saturated_into::<usize>() {
|
||||
let current_ratio = assignment.1[i % len].1;
|
||||
let next_ratio = current_ratio.saturating_add(Perbill::from_parts(1));
|
||||
let next_ratio = current_ratio.saturating_add(R::from_parts(1u8.into()));
|
||||
assignment.1[i % len].1 = next_ratio;
|
||||
}
|
||||
assigned.push(assignment);
|
||||
@@ -341,15 +351,16 @@ pub fn elect<AccountId, Balance, FS, C>(
|
||||
}
|
||||
|
||||
/// Build the support map from the given phragmen result.
|
||||
pub fn build_support_map<Balance, AccountId, FS, C>(
|
||||
pub fn build_support_map<Balance, AccountId, FS, C, R>(
|
||||
elected_stashes: &Vec<AccountId>,
|
||||
assignments: &Vec<(AccountId, Vec<PhragmenAssignment<AccountId>>)>,
|
||||
assignments: &Vec<(AccountId, Vec<PhragmenAssignment<AccountId, R>>)>,
|
||||
stake_of: FS,
|
||||
) -> SupportMap<AccountId> where
|
||||
AccountId: Default + Ord + Member,
|
||||
Balance: Default + Copy + SimpleArithmetic,
|
||||
Balance: Default + Copy + AtLeast32Bit,
|
||||
C: Convert<Balance, u64> + Convert<u128, Balance>,
|
||||
for<'r> FS: Fn(&'r AccountId) -> Balance,
|
||||
R: PerThing + sp_std::ops::Mul<ExtendedBalance, Output=ExtendedBalance>,
|
||||
{
|
||||
let to_votes = |b: Balance| <C as Convert<Balance, u64>>::convert(b) as ExtendedBalance;
|
||||
// Initialize the support of each candidate.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
use crate::{elect, PhragmenResult, PhragmenAssignment};
|
||||
use sp_runtime::{
|
||||
assert_eq_error_rate, Perbill,
|
||||
assert_eq_error_rate, Perbill, PerThing,
|
||||
traits::{Convert, Member, SaturatedConversion}
|
||||
};
|
||||
use sp_std::collections::btree_map::BTreeMap;
|
||||
@@ -320,10 +320,10 @@ pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)])
|
||||
}
|
||||
|
||||
|
||||
pub fn check_assignments(assignments: Vec<(AccountId, Vec<PhragmenAssignment<AccountId>>)>) {
|
||||
pub fn check_assignments(assignments: Vec<(AccountId, Vec<PhragmenAssignment<AccountId, Perbill>>)>) {
|
||||
for (_, a) in assignments {
|
||||
let sum: u32 = a.iter().map(|(_, p)| p.deconstruct()).sum();
|
||||
assert_eq_error_rate!(sum, Perbill::accuracy(), 5);
|
||||
assert_eq_error_rate!(sum, Perbill::ACCURACY, 5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ pub(crate) fn run_and_compare(
|
||||
min_to_elect: usize,
|
||||
) {
|
||||
// run fixed point code.
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Perbill>(
|
||||
to_elect,
|
||||
min_to_elect,
|
||||
candidates.clone(),
|
||||
|
||||
@@ -23,6 +23,8 @@ use crate::{elect, PhragmenResult, PhragmenStakedAssignment, build_support_map,
|
||||
use substrate_test_utils::assert_eq_uvec;
|
||||
use sp_runtime::Perbill;
|
||||
|
||||
type Output = Perbill;
|
||||
|
||||
#[test]
|
||||
fn float_phragmen_poc_works() {
|
||||
let candidates = vec![1, 2, 3];
|
||||
@@ -78,7 +80,7 @@ fn phragmen_poc_works() {
|
||||
(30, vec![2, 3]),
|
||||
];
|
||||
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
2,
|
||||
2,
|
||||
candidates,
|
||||
@@ -147,7 +149,7 @@ fn phragmen_accuracy_on_large_scale_only_validators() {
|
||||
(5, (u64::max_value() - 2).into()),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
2,
|
||||
2,
|
||||
candidates.clone(),
|
||||
@@ -178,7 +180,7 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() {
|
||||
(14, u64::max_value().into()),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
2,
|
||||
2,
|
||||
candidates,
|
||||
@@ -210,7 +212,7 @@ fn phragmen_accuracy_on_small_scale_self_vote() {
|
||||
(30, 1),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
3,
|
||||
3,
|
||||
candidates,
|
||||
@@ -241,7 +243,7 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() {
|
||||
(3, 1),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
3,
|
||||
3,
|
||||
candidates,
|
||||
@@ -275,7 +277,7 @@ fn phragmen_large_scale_test() {
|
||||
(50, 990000000000000000),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
2,
|
||||
2,
|
||||
candidates,
|
||||
@@ -302,7 +304,7 @@ fn phragmen_large_scale_test_2() {
|
||||
(50, nom_budget.into()),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
2,
|
||||
2,
|
||||
candidates,
|
||||
@@ -367,7 +369,7 @@ fn elect_has_no_entry_barrier() {
|
||||
(2, 10),
|
||||
]);
|
||||
|
||||
let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
3,
|
||||
3,
|
||||
candidates,
|
||||
@@ -395,7 +397,7 @@ fn minimum_to_elect_is_respected() {
|
||||
(2, 10),
|
||||
]);
|
||||
|
||||
let maybe_result = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let maybe_result = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
10,
|
||||
10,
|
||||
candidates,
|
||||
@@ -422,7 +424,7 @@ fn self_votes_should_be_kept() {
|
||||
(1, 8),
|
||||
]);
|
||||
|
||||
let result = elect::<_, _, _, TestCurrencyToVote>(
|
||||
let result = elect::<_, _, _, TestCurrencyToVote, Output>(
|
||||
2,
|
||||
2,
|
||||
candidates,
|
||||
@@ -448,7 +450,8 @@ fn self_votes_should_be_kept() {
|
||||
Balance,
|
||||
AccountId,
|
||||
_,
|
||||
TestCurrencyToVote
|
||||
TestCurrencyToVote,
|
||||
Output,
|
||||
>(
|
||||
&result.winners.into_iter().map(|(who, _)| who).collect(),
|
||||
&result.assignments,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Provides some utilities to define a piecewise linear function.
|
||||
|
||||
use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}};
|
||||
use crate::{Perbill, PerThing, traits::{AtLeast32Bit, SaturatedConversion}};
|
||||
use core::ops::Sub;
|
||||
|
||||
/// Piecewise Linear function in [0, 1] -> [0, 1].
|
||||
@@ -35,7 +35,7 @@ fn abs_sub<N: Ord + Sub<Output=N> + Clone>(a: N, b: N) -> N where {
|
||||
impl<'a> PiecewiseLinear<'a> {
|
||||
/// Compute `f(n/d)*d` with `n <= d`. This is useful to avoid loss of precision.
|
||||
pub fn calculate_for_fraction_times_denominator<N>(&self, n: N, d: N) -> N where
|
||||
N: SimpleArithmetic + Clone
|
||||
N: AtLeast32Bit + Clone
|
||||
{
|
||||
let n = n.min(d.clone());
|
||||
|
||||
@@ -79,7 +79,7 @@ impl<'a> PiecewiseLinear<'a> {
|
||||
// This is guaranteed not to overflow on whatever values nor lose precision.
|
||||
// `q` must be superior to zero.
|
||||
fn multiply_by_rational_saturating<N>(value: N, p: u32, q: u32) -> N
|
||||
where N: SimpleArithmetic + Clone
|
||||
where N: AtLeast32Bit + Clone
|
||||
{
|
||||
let q = q.max(1);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error};
|
||||
use crate::traits::{
|
||||
self, Member, SimpleArithmetic, SimpleBitOps, Hash as HashT,
|
||||
self, Member, AtLeast32Bit, SimpleBitOps, Hash as HashT,
|
||||
MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay,
|
||||
MaybeMallocSizeOf,
|
||||
};
|
||||
@@ -122,7 +122,7 @@ impl<Number, Hash> codec::EncodeLike for Header<Number, Hash> where
|
||||
|
||||
impl<Number, Hash> traits::Header for Header<Number, Hash> where
|
||||
Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay +
|
||||
SimpleArithmetic + Codec + Copy + Into<U256> + TryFrom<U256> + sp_std::str::FromStr +
|
||||
AtLeast32Bit + Codec + Copy + Into<U256> + TryFrom<U256> + sp_std::str::FromStr +
|
||||
MaybeMallocSizeOf,
|
||||
Hash: HashT,
|
||||
Hash::Output: Default + sp_std::hash::Hash + Copy + Member + Ord +
|
||||
@@ -170,7 +170,7 @@ impl<Number, Hash> traits::Header for Header<Number, Hash> where
|
||||
}
|
||||
|
||||
impl<Number, Hash> Header<Number, Hash> where
|
||||
Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into<U256> + TryFrom<U256>,
|
||||
Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32Bit + Codec + Into<U256> + TryFrom<U256>,
|
||||
Hash: HashT,
|
||||
Hash::Output: Default + sp_std::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ pub use sp_application_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic};
|
||||
pub use sp_core::RuntimeDebug;
|
||||
|
||||
/// Re-export top-level arithmetic stuff.
|
||||
pub use sp_arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64};
|
||||
pub use sp_arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64, PerThing};
|
||||
/// Re-export 128 bit helpers.
|
||||
pub use sp_arithmetic::helpers_128bit;
|
||||
/// Re-export big_uint stuff.
|
||||
|
||||
@@ -33,7 +33,7 @@ use crate::transaction_validity::{
|
||||
};
|
||||
use crate::generic::{Digest, DigestItem};
|
||||
pub use sp_arithmetic::traits::{
|
||||
SimpleArithmetic, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion,
|
||||
AtLeast32Bit, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion,
|
||||
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
|
||||
CheckedShl, CheckedShr, IntegerSquareRoot
|
||||
};
|
||||
@@ -502,7 +502,7 @@ pub trait Header:
|
||||
{
|
||||
/// Header number.
|
||||
type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash
|
||||
+ Copy + MaybeDisplay + SimpleArithmetic + Codec + sp_std::str::FromStr
|
||||
+ Copy + MaybeDisplay + AtLeast32Bit + Codec + sp_std::str::FromStr
|
||||
+ MaybeMallocSizeOf;
|
||||
/// Header hash type
|
||||
type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord
|
||||
|
||||
@@ -87,7 +87,7 @@ where
|
||||
P: TransactionPool + 'static,
|
||||
Block: traits::Block,
|
||||
AccountId: Clone + std::fmt::Display + Codec,
|
||||
Index: Clone + std::fmt::Display + Codec + Send + traits::SimpleArithmetic + 'static,
|
||||
Index: Clone + std::fmt::Display + Codec + Send + traits::AtLeast32Bit + 'static,
|
||||
{
|
||||
fn nonce(&self, account: AccountId) -> FutureResult<Index> {
|
||||
let get_nonce = || {
|
||||
@@ -141,7 +141,7 @@ where
|
||||
F: Fetcher<Block> + 'static,
|
||||
Block: traits::Block,
|
||||
AccountId: Clone + std::fmt::Display + Codec + Send + 'static,
|
||||
Index: Clone + std::fmt::Display + Codec + Send + traits::SimpleArithmetic + 'static,
|
||||
Index: Clone + std::fmt::Display + Codec + Send + traits::AtLeast32Bit + 'static,
|
||||
{
|
||||
fn nonce(&self, account: AccountId) -> FutureResult<Index> {
|
||||
let best_hash = self.client.info().best_hash;
|
||||
@@ -189,7 +189,7 @@ fn adjust_nonce<P, AccountId, Index>(
|
||||
) -> Index where
|
||||
P: TransactionPool,
|
||||
AccountId: Clone + std::fmt::Display + Encode,
|
||||
Index: Clone + std::fmt::Display + Encode + traits::SimpleArithmetic + 'static,
|
||||
Index: Clone + std::fmt::Display + Encode + traits::AtLeast32Bit + 'static,
|
||||
{
|
||||
log::debug!(target: "rpc", "State nonce for {}: {}", account, nonce);
|
||||
// Now we need to query the transaction pool
|
||||
|
||||
Reference in New Issue
Block a user