mirror of
https://git.ghostchain.io/proxmio/ghost-node.git
synced 2025-12-27 11:19:57 +00:00
inital commit, which is clearly not initial
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
26
runtime/common/src/benchmarking.rs
Normal file
26
runtime/common/src/benchmarking.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use primitives::{AccountId, Balance};
|
||||
use pallet_treasury::ArgumentsFactory;
|
||||
use sp_core::crypto::FromEntropy;
|
||||
use frame_support::traits::tokens::{Pay, PaymentStatus};
|
||||
|
||||
pub struct BenchmarkTreasuryHelper;
|
||||
impl ArgumentsFactory<(), AccountId> for BenchmarkTreasuryHelper {
|
||||
fn create_asset_kind(_seed: u32) -> () { () }
|
||||
fn create_beneficiary(seed: [u8; 32]) -> AccountId {
|
||||
AccountId::from_entropy(&mut seed.as_slice()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BenchmarkTreasuryPaymaster;
|
||||
impl Pay for BenchmarkTreasuryPaymaster {
|
||||
type Beneficiary = AccountId;
|
||||
type Balance = Balance;
|
||||
type Id = ();
|
||||
type AssetKind = ();
|
||||
type Error = ();
|
||||
|
||||
fn pay(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) -> Result<Self::Id, Self::Error> { Ok(()) }
|
||||
fn check_payment(_: Self::Id) -> PaymentStatus { PaymentStatus::Success }
|
||||
fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) {}
|
||||
fn ensure_concluded(_: Self::Id) {}
|
||||
}
|
||||
42
runtime/common/src/elections.rs
Normal file
42
runtime/common/src/elections.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
#[macro_export]
|
||||
macro_rules! impl_elections_weights {
|
||||
($runtime:ident) => {
|
||||
parameter_types! {
|
||||
/// A limit for off-chain phragmen unsigned solution submission.
|
||||
///
|
||||
/// We want to keep it as high as possible, but can't risk having
|
||||
/// it reject, so we always substract the base block execution weight.
|
||||
pub OffchainSolutionWeightLimit: Weight = BlockWeights::get()
|
||||
.get(DispatchClass::Normal)
|
||||
.max_extrinsic
|
||||
.expect("Normal extrinsic have weight limit configured by default; qed")
|
||||
.saturating_sub($runtime::weights::BlockExecutionWeight::get());
|
||||
|
||||
/// A limit for off-chain phragmen unsigned solution length.
|
||||
///
|
||||
/// We allow up to 90% of the block's size to be consumed by the solution.
|
||||
pub OffchainSolutionLengthLimit: u32 = Perbill::from_rational(90u32, 100u32) *
|
||||
*BlockLength::get()
|
||||
.max
|
||||
.get(DispatchClass::Normal);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// The number configured here could always be more than the maximum limits of
|
||||
/// staking pallet to ensure election snapshot will not run out of memory. For
|
||||
/// now, we set them to smaller values since the staking is bounded and the weight
|
||||
/// pipeline takes for this single pallet.
|
||||
pub struct BenchmarkConfig;
|
||||
impl pallet_election_provider_multi_phase::BenchmarkingConfig for BenchmarkConfig {
|
||||
const VOTERS: [u32; 2] = [1000, 2000];
|
||||
const TARGETS: [u32; 2] = [500, 1000];
|
||||
const ACTIVE_VOTERS: [u32; 2] = [500, 800];
|
||||
const DESIRED_TARGETS: [u32; 2] = [200, 400];
|
||||
const SNAPSHOT_MAXIMUM_VOTERS: u32 = 1000;
|
||||
const MINER_MAXIMUM_VOTERS: u32 = 1000;
|
||||
const MAXIMUM_TARGETS: u32 = 300;
|
||||
}
|
||||
|
||||
/// The accuracy type used for genesis election provider.
|
||||
pub type OnChainAccuracy = sp_runtime::Perbill;
|
||||
253
runtime/common/src/impls.rs
Executable file
253
runtime/common/src/impls.rs
Executable file
@@ -0,0 +1,253 @@
|
||||
use frame_support::traits::{
|
||||
fungible::{Balanced, Credit},
|
||||
tokens::imbalance::ResolveTo,
|
||||
Imbalance, OnUnbalanced,
|
||||
};
|
||||
use pallet_treasury::TreasuryAccountId;
|
||||
|
||||
/// The logic for the author to get a portion of fees.
|
||||
pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>);
|
||||
impl<R> OnUnbalanced<Credit<R::AccountId, pallet_balances::Pallet<R>>> for ToAuthor<R>
|
||||
where
|
||||
R: pallet_balances::Config + pallet_authorship::Config,
|
||||
<R as frame_system::Config>::AccountId: From<primitives::AccountId>,
|
||||
<R as frame_system::Config>::AccountId: Into<primitives::AccountId>,
|
||||
{
|
||||
fn on_nonzero_unbalanced(
|
||||
amount: Credit<<R as frame_system::Config>::AccountId, pallet_balances::Pallet<R>>,
|
||||
) {
|
||||
if let Some(author) = <pallet_authorship::Pallet<R>>::author() {
|
||||
let _ = <pallet_balances::Pallet<R>>::resolve(&author, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DealWithFees<R>(sp_std::marker::PhantomData<R>);
|
||||
impl<R> OnUnbalanced<Credit<R::AccountId, pallet_balances::Pallet<R>>> for DealWithFees<R>
|
||||
where
|
||||
R: pallet_balances::Config + pallet_treasury::Config + pallet_authorship::Config,
|
||||
<R as frame_system::Config>::AccountId: From<primitives::AccountId>,
|
||||
<R as frame_system::Config>::AccountId: Into<primitives::AccountId>,
|
||||
{
|
||||
// this seems to be called for substrate-based transactions
|
||||
fn on_unbalanceds<B>(
|
||||
mut fees_then_tips: impl Iterator<Item = Credit<R::AccountId, pallet_balances::Pallet<R>>>,
|
||||
) {
|
||||
if let Some(fees) = fees_then_tips.next() {
|
||||
// for fees, 80% to treasury, 20% to author
|
||||
let mut split = fees.ration(80, 20);
|
||||
if let Some(tips) = fees_then_tips.next() {
|
||||
// for tips, if any, 100% to author
|
||||
tips.merge_into(&mut split.1);
|
||||
}
|
||||
ResolveTo::<TreasuryAccountId<R>, pallet_balances::Pallet<R>>::on_unbalanced(split.0);
|
||||
<ToAuthor<R> as OnUnbalanced<_>>::on_unbalanced(split.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use frame_support::{
|
||||
derive_impl,
|
||||
dispatch::DispatchClass,
|
||||
parameter_types,
|
||||
traits::{
|
||||
tokens::{PayFromAccount, UnityAssetBalanceConversion},
|
||||
ConstU32, FindAuthor
|
||||
},
|
||||
weights::Weight,
|
||||
PalletId,
|
||||
};
|
||||
use frame_system::limits;
|
||||
use primitives::AccountId;
|
||||
use sp_core::{ConstU64, H256};
|
||||
use sp_runtime::{
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
Perbill, BuildStorage,
|
||||
};
|
||||
|
||||
type Block = frame_system::mocking::MockingBlock<Test>;
|
||||
const TEST_ACCOUNT: AccountId = AccountId::new([1; 32]);
|
||||
|
||||
frame_support::construct_runtime!(
|
||||
pub enum Test
|
||||
{
|
||||
System: frame_system,
|
||||
Authorship: pallet_authorship,
|
||||
Balances: pallet_balances,
|
||||
Treasury: pallet_treasury,
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
|
||||
.base_block(Weight::from_parts(10, 0))
|
||||
.for_class(DispatchClass::all(), |weight| {
|
||||
weight.base_extrinsic = Weight::from_parts(100, 0);
|
||||
})
|
||||
.for_class(DispathcClass::non_mandatory(), |weight| {
|
||||
weight.max_total = Some(Weight::from_parts(1024, u64::MAX));
|
||||
})
|
||||
.build_or_panic();
|
||||
pub BlockLength: limits::BlockLength = limits::BlockLength::max(2 * 1024);
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::one();
|
||||
}
|
||||
|
||||
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
|
||||
impl frame_system::Config for Test {
|
||||
type BaseCallFilter = frame_support::traits::Everything;
|
||||
type RuntimeOrigin = RuntimeOrigin;
|
||||
type Nonce = u64;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = AccountId;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Block = Block;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BlockLength = BlockLength;
|
||||
type BlockWeights = BlockWeghts;
|
||||
type DbWeight = ();
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = pallet_balances::AccountData<u64>;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = ();
|
||||
type OnSetCode = ();
|
||||
type MaxConsumers = frame_support::traits::ConstU32<16>;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
type Balance = u64;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ConstU64<1>;
|
||||
type AccountStore = System;
|
||||
type MaxLocks = ();
|
||||
type MaxReserves = ();
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
type WeightInfo = ();
|
||||
type RuntimeHoldReason = RuntimeHoldReason;
|
||||
type RuntimeFreezeReason = RuntimeFreezeReason;
|
||||
type FreezeIdentifier = ();
|
||||
type MaxFreezes = ConstU32<1>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const TreasuryPalletId: PalletId = PalletId(*b"g/trsry");
|
||||
pub const MaxApprovals: u32 = 100;
|
||||
pub TreasuryAccount: AccountId = Treasury::account_id();
|
||||
}
|
||||
|
||||
impl pallet_treasury::Config for Runtime {
|
||||
type Currency = pallet_balances::Pallet<Test>;
|
||||
type ApproveOrigin = frame_system::EnsureRoot<AccountId>;
|
||||
type RejectOrigin = frame_system::EnsureRoot<AccountId>;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type OnSlash = ();
|
||||
type ProposalBond = ();
|
||||
type ProposalBondMaximum = ();
|
||||
type ProposalBondMinimum = ();
|
||||
type SpendPeriod = ();
|
||||
type Burn = ();
|
||||
type BurnDestination = ();
|
||||
type PalletId = TreasuryPalletId;
|
||||
type SpendFunds = ();
|
||||
type MaxApprovals = MaxApprovals;
|
||||
type WeightInfo = ();
|
||||
type SpendOrigin = frame_support::traits::NeverEnsureOrigin<u64>;
|
||||
type AssetKind = ();
|
||||
type Beneficiary = Self::AccountId;
|
||||
type BeneficiaryLookup = IdentityLookup<Self::AccountId>;
|
||||
type Paymaster = PayFromAccount<Balances, TreasuryAccount>;
|
||||
type BalanceConverter = UnityAssetBalanceConversion;
|
||||
type PayoutPeriod = ConstU64<0>;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type BenchmarkHelper = ();
|
||||
}
|
||||
|
||||
pub struct OneAuthor;
|
||||
impl FindAuthor<AccountId> for OneAuthor {
|
||||
fn find_author<'a, I>(_: I) -> Option<AccountId> where I: 'a {
|
||||
Some(TEST_ACCOUNT)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_authorship::Config for Runtime {
|
||||
type FindAuthor = OneAuthor;
|
||||
type UncleGenerations = ();
|
||||
type FilterUncle = ();
|
||||
type EventHandler = ();
|
||||
}
|
||||
|
||||
pub fn new_test_ext() -> sp_io::TestExternalities {
|
||||
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
|
||||
// We use default for brevity, but you can configure as desired if needed.
|
||||
pallet_balances::GenesisConfig::<Test>::default()
|
||||
.assimilate_storage(&mut t)
|
||||
.unwrap();
|
||||
t.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fees_and_tips_split() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let fee = <paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<AccountId>>::issue(10);
|
||||
let tip = <paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<AccountId>>::issue(20);
|
||||
|
||||
assert_eq!(Balances::free_balance(Treasury::account_id()), 0);
|
||||
assert_eq!(Balances::free_balance(TEST_ACCOUNT), 0);
|
||||
|
||||
DealWithFees::on_unbalanced(vec![fee, tip].into_iter());
|
||||
|
||||
// Author gets 100% of tip and 20% of fee = 22
|
||||
assert_eq!(Balances::free_balance(TEST_ACCOUNT), 22);
|
||||
// Treasury get 80% of fee
|
||||
assert_eq!(Balances::free_balance(Treasury::account_id()), 8);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_inflation_should_give_sensible_results() {
|
||||
assert_eq!(
|
||||
pallet_staking_reward_fn::compute_inflation(
|
||||
Perquintill::from_percent(75),
|
||||
Perquintill::from_percent(75),
|
||||
Perquintill::from_percent(5),
|
||||
),
|
||||
Perquintill::one()
|
||||
);
|
||||
assert_eq!(
|
||||
pallet_staking_reward_fn::compute_inflation(
|
||||
Perquintill::from_percent(50),
|
||||
Perquintill::from_percent(75),
|
||||
Perquintill::from_percent(5),
|
||||
),
|
||||
Perquintill::from_rational(2u64, 3u64)
|
||||
);
|
||||
assert_eq!(
|
||||
pallet_staking_reward_fn::compute_inflation(
|
||||
Perquintill::from_percent(80),
|
||||
Perquintill::from_percent(75),
|
||||
Perquintill::from_percent(5),
|
||||
),
|
||||
Perquintill::fram_rational(1u64, 2u64)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn era_payout_should_give_sensible_results() {
|
||||
assert_eq!(
|
||||
era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0, ),
|
||||
(10, 0)
|
||||
);
|
||||
assert_eq!(
|
||||
era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0, ),
|
||||
(6, 4)
|
||||
);
|
||||
}
|
||||
}
|
||||
186
runtime/common/src/lib.rs
Executable file
186
runtime/common/src/lib.rs
Executable file
@@ -0,0 +1,186 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
pub mod impls;
|
||||
pub mod elections;
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
pub mod elections;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub mod benchmarking;
|
||||
|
||||
use frame_support::{
|
||||
parameter_types, traits::ConstU32,
|
||||
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight},
|
||||
};
|
||||
use frame_system::limits;
|
||||
use primitives::{Balance, BlockNumber};
|
||||
use sp_runtime::{FixedPointNumber, Perbill, Perquintill};
|
||||
use static_assertions::const_assert;
|
||||
|
||||
pub use pallet_balances::Call as BalancesCall;
|
||||
#[cfg(feature = "std")]
|
||||
pub use pallet_staking::StakerStatus;
|
||||
pub use pallet_timestamp::{Call as TimestampCall};
|
||||
use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
|
||||
pub use sp_runtime::traits::Bounded;
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
|
||||
pub use impls::ToAuthor;
|
||||
|
||||
/// We assume that an on-initialize consumes 1% of the weight on average, hence
|
||||
/// a single extrinsic will not be allowed to consume more than
|
||||
/// `AvailableBlockRatio - 1%`.
|
||||
pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(1);
|
||||
|
||||
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can
|
||||
/// be used by `Operational` extrinsics.
|
||||
pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
|
||||
|
||||
/// We allow for 2 seconds of compute with a 6 seconds average block time.
|
||||
/// The storage proof size is not limited so far.
|
||||
pub const MAXIMUM_BLOCK_WEIGHT: Weight =
|
||||
Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
|
||||
|
||||
const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());
|
||||
|
||||
// Common constants used in all runtimes.
|
||||
parameter_types! {
|
||||
/// Maximum amount of block to be stored in ledger.
|
||||
pub const BlockHashCount: BlockNumber = 4096;
|
||||
|
||||
/// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees
|
||||
/// with. Blocks filled less than will decrease the weight and more will
|
||||
/// increase.
|
||||
pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
|
||||
|
||||
/// The adjustment variable of the runtime. Higher values will cause
|
||||
/// `TargetBlockFullness` to change the fees more rapidly.
|
||||
pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1_000_000);
|
||||
|
||||
/// Minimum amount of the multiplier. This value cannot be too low. A test
|
||||
/// case should ensure that combined with `AdjustmentVariable`, we can
|
||||
/// recover from the minimum.
|
||||
pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128);
|
||||
|
||||
/// The maximum amount of the multiplier.
|
||||
pub MaximumMultiplier: Multiplier = Bounded::max_value();
|
||||
|
||||
/// Maximum length of block. Up to 5MB.
|
||||
pub BlockLength: limits::BlockLength =
|
||||
limits::BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
|
||||
}
|
||||
|
||||
/// Parametrized slow adjusting fee.
|
||||
pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
|
||||
R,
|
||||
TargetBlockFullness,
|
||||
AdjustmentVariable,
|
||||
MinimumMultiplier,
|
||||
MaximumMultiplier,
|
||||
>;
|
||||
|
||||
/// Implements the weight types for a runtime.
|
||||
/// It expects the passed runtime constants to contain a `weights` module.
|
||||
/// The generated weight types were formerly part of the common
|
||||
/// runtime but are now runtime dependant.
|
||||
#[macro_export]
|
||||
macro_rules! impl_runtime_weights {
|
||||
($runtime:ident) => {
|
||||
use frame_support::{dispatch::DispatchClass, weights::Weight};
|
||||
use frame_system::limits;
|
||||
use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
|
||||
pub use runtime_common::{
|
||||
impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO,
|
||||
MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
|
||||
};
|
||||
use sp_runtime::{FixedPointNumber, Perquintill};
|
||||
|
||||
impl_elections_weights!($runtime);
|
||||
|
||||
// Expose the weight from the runtime constants module.
|
||||
pub use $runtime::weights::{
|
||||
BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
|
||||
ParityDbWeight,
|
||||
};
|
||||
|
||||
parameter_types! {
|
||||
/// Block weights base values and limits.
|
||||
pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
|
||||
.base_block($runtime::weights::BlockExecutionWeight::get())
|
||||
.for_class(DispatchClass::all(), |weights| {
|
||||
weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get();
|
||||
})
|
||||
.for_class(DispatchClass::Normal, |weights| {
|
||||
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
|
||||
})
|
||||
.for_class(DispatchClass::Operational, |weights| {
|
||||
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
|
||||
// Operational transactions have an extra reserved space, so that they
|
||||
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
|
||||
weights.reserved = Some(
|
||||
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT,
|
||||
);
|
||||
})
|
||||
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
|
||||
.build_or_panic();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// The type used for currency conversion.
|
||||
///
|
||||
/// This must be only be used as long as the balance type is `u128`.
|
||||
pub type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
|
||||
static_assertions::assert_eq_size!(primitives::Balance, u128);
|
||||
|
||||
/// A reasonable benchmarking config for staking pallet.
|
||||
pub struct StakingBenchmarkingConfig;
|
||||
impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
|
||||
type MaxValidators = ConstU32<1000>;
|
||||
type MaxNominators = ConstU32<1000>;
|
||||
}
|
||||
|
||||
/// Convert a balance to an unsigned 256-bit number, use in nomination pools.
|
||||
pub struct BalanceToU256;
|
||||
impl sp_runtime::traits::Convert<Balance, sp_core::U256> for BalanceToU256 {
|
||||
fn convert(n: Balance) -> sp_core::U256 {
|
||||
n.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert an unsigned 256-bit number to balance, use in nomination pools.
|
||||
pub struct U256ToBalance;
|
||||
impl sp_runtime::traits::Convert<sp_core::U256, Balance> for U256ToBalance {
|
||||
fn convert(n: sp_core::U256) -> Balance {
|
||||
use frame_support::traits::Defensive;
|
||||
n.try_into().defensive_unwrap_or(Balance::MAX)
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro to set a value (e.g. when using the `parameter_types` macro) to
|
||||
/// either a production value or to an environment variable or testing value
|
||||
/// ( in case the `fast-runtime` feature is selected).
|
||||
/// Note that the environment varable is evaluated _at compile time_.
|
||||
#[macro_export]
|
||||
macro_rules! prod_or_fast {
|
||||
($prod:expr, $test:expr) => {
|
||||
if cfg!(feature = "fast-runtime") {
|
||||
$test
|
||||
} else {
|
||||
$prod
|
||||
}
|
||||
};
|
||||
($prod:expr, $test:expr, $env:expr) => {
|
||||
if cfg!(feature == "fast-runtime") {
|
||||
core::option_env!($env)
|
||||
.map(|s| s.parse().ok())
|
||||
.flatten()
|
||||
.unwrap_or($test)
|
||||
} else {
|
||||
$prod
|
||||
}
|
||||
};
|
||||
}
|
||||
96
runtime/common/src/try_runtime.rs
Normal file
96
runtime/common/src/try_runtime.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use frame_support::{
|
||||
dispatch::RawOrigin,
|
||||
traits::{Get, Hooks},
|
||||
};
|
||||
use pallet_fast_unstake::{Pallet as FastUnstake, *};
|
||||
use pallet_staking::*;
|
||||
use sp_std::{collections::btree_set::BTreeSet, prelude:*};
|
||||
|
||||
/// Register all inactive nominators for fast unstake, and progress until they
|
||||
/// have all benn processed.
|
||||
pub fn migrate_all_inactive_nominators<T: pallet_fast_unstake::Config + pallet_staking::Config>()
|
||||
where
|
||||
<T as frame_system::Config>::RuntimeEvent: TryInto<pallet_fast_unstake::Event<T>>,
|
||||
{
|
||||
let mut unstaked_ok = 0;
|
||||
let mut unstaked_err = 0;
|
||||
let mut unstaked_slashed = 0;
|
||||
|
||||
let all_stakers = Ledger::<T>::iter().map(|(ctrl, l)| (ctrl, l.stash)).collect::<BTreeSet<_>>();
|
||||
let mut all_exposed = BTreeSet::new();
|
||||
ErasStakers::<T>::iter().for_each(|(_, val, expo)| {
|
||||
all_exposed.insert(val);
|
||||
all_exposed.extend(expo.others.iter().map(|ie| ie.who.clone()))
|
||||
});
|
||||
|
||||
let eligible = all_stakers
|
||||
.iter()
|
||||
.filter_map(|(ctrl, stash)| all_exposed.contains(stash).then_some(ctrl))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
log::info!(
|
||||
target: "runtime::test",
|
||||
"registering {} out of {} stakers for fast-unstake",
|
||||
eligible.len(),
|
||||
all_stakers.len(),
|
||||
);
|
||||
|
||||
for ctrl in eligible {
|
||||
if let Err(why) =
|
||||
FastUnstake::<T>::register_fast_unstake(RawOrigin::Signed(ctrl.clone()).into())
|
||||
{
|
||||
low::warn!(target: "runtime::test", "failed to register {:?} due to {:?}", ctrl, why);
|
||||
}
|
||||
}
|
||||
|
||||
log::info!(
|
||||
target: "runtime::test",
|
||||
"registered {} successfully, starting at {:?}.",
|
||||
Queue::<T>::count(),
|
||||
frame_system::Pallet::<T>::block_number(),
|
||||
);
|
||||
|
||||
while Queue::<T>::count() != 0 || Head::<T>::get().is_some() {
|
||||
let not = frame_system::Pallet::<T>::block_number();
|
||||
let weight = <T as frame_system::Config>::BlockWeights::get().max_block;
|
||||
let consumed = FastUnstake::<T>::on_idle(now, weight);
|
||||
log::debug!(
|
||||
target: "runtime::test",
|
||||
"consumed {:?} ({})",
|
||||
consumed,
|
||||
consumed.ref_time() as f32 / weight.ref_time() as f32,
|
||||
);
|
||||
|
||||
frame_system::Pallet::<T>::read_events_on_consensus()
|
||||
.into_iter()
|
||||
.map(|r| r.event)
|
||||
.filter_map(|e| {
|
||||
let maybe_fast_unstake_event: Option<pallet_fast_unstake::Event<T>> =
|
||||
e.try_into().ok();
|
||||
maybe_fast_unstake_event
|
||||
})
|
||||
.for_each(|e: pallet_fast_unstake::Event<T>| match e {
|
||||
pallet_fast_unstake::Event<T>::Unstaked { result, .. } =>
|
||||
if result.is_ok() {
|
||||
unstaked_ok += 1;
|
||||
} else {
|
||||
unstaked_err += 1;
|
||||
},
|
||||
pallet_fast_unstake::Event::<T>::Slashed { .. } => unstaked_slashed += 1,
|
||||
pallet_fast_unstake::Event::<T>::InternalError { .. } => unreachable!(),
|
||||
_ => {},
|
||||
});
|
||||
|
||||
if now % 100u32.into() == sp_runtime::traits::Zero::zero() {
|
||||
log::info!(
|
||||
target: "runtime::test",
|
||||
"status: ok {}, err {}, slash {}",
|
||||
unstaked_ok,
|
||||
unstaked_err,
|
||||
unstaked_slashed,
|
||||
);
|
||||
}
|
||||
|
||||
frame_system::Pallet::<T>::reset_events();
|
||||
}
|
||||
}
|
||||
27
runtime/common/src/weights/block_weights.rs
Executable file
27
runtime/common/src/weights/block_weights.rs
Executable file
@@ -0,0 +1,27 @@
|
||||
use sp_core::parameter_types;
|
||||
use sp_weights::{constants::WEIGHT_PER_TIME_PER_NANOS, Weight};
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockExecutionWeight: Weight =
|
||||
Weight::from_ref_time(WEIGHT_PER_TIME_PER_NANOS.saturating_mul(7_955_558));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_weights {
|
||||
use sp_weights::constants;
|
||||
|
||||
#[test]
|
||||
fn sane() {
|
||||
let w = super::BlockExecutionWeight::get();
|
||||
|
||||
assert!(
|
||||
w.ref_time() >= 100u64 * constants::WEIGHT_PER_TIME_PER_MICROS,
|
||||
"Weight should be at least 100 µs."
|
||||
);
|
||||
|
||||
assert!(
|
||||
w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||
"Weight should be at most 50 ms."
|
||||
);
|
||||
}
|
||||
}
|
||||
27
runtime/common/src/weights/extrinsic.rs
Executable file
27
runtime/common/src/weights/extrinsic.rs
Executable file
@@ -0,0 +1,27 @@
|
||||
use sp_core::parameter_types;
|
||||
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
|
||||
|
||||
parameter_types! {
|
||||
pub const ExtrinsicBaseWeight: Weight =
|
||||
Weight::from_ref_time(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(94_914));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_weights {
|
||||
use sp_weights::constants;
|
||||
|
||||
#[test]
|
||||
fn sane() {
|
||||
let w = super::ExtrinsicBaseWeight::get();
|
||||
|
||||
assert!(
|
||||
w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||
"Weight should be at least 10 µs."
|
||||
);
|
||||
|
||||
assert!(
|
||||
w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||
"Weight should be at most 1 ms."
|
||||
);
|
||||
}
|
||||
}
|
||||
5
runtime/common/src/weights/mod.rs
Executable file
5
runtime/common/src/weights/mod.rs
Executable file
@@ -0,0 +1,5 @@
|
||||
pub mod block_weights;
|
||||
pub mod extrinsic_weight;
|
||||
|
||||
pub use block_weights::BlockExecutionWeight;
|
||||
pub use extrinsic_weights::ExtrinsicBaseWeight;
|
||||
Reference in New Issue
Block a user