mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 09:21:04 +00:00
e0d6b95a90
* Introduce `OriginPrivilegeCmp` Make use of the new `OriginPrivilegeCmp` feature of pallet scheduler. The idea is to make sure that a council origin with more yes votes has higher privileges than a council origin with less yes votes. This solves a problem that happened recently on Kusama where the council tried to cancel a scheduled task, but that required that the same council origin was used while the cancel motion had more yes votes than the origin motion that scheduled this task. With this origin privilege compare it should now be solved by checking the yes votes directly. * Feedback * update lockfile for substrate Co-authored-by: parity-processbot <>
2059 lines
74 KiB
Rust
2059 lines
74 KiB
Rust
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
|
|
// This file is part of Polkadot.
|
|
|
|
// Polkadot is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// Polkadot is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//! The Kusama runtime. This can be compiled with `#[no_std]`, ready for Wasm.
|
|
|
|
#![cfg_attr(not(feature = "std"), no_std)]
|
|
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
|
|
#![recursion_limit = "256"]
|
|
|
|
use pallet_transaction_payment::CurrencyAdapter;
|
|
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
|
|
use primitives::v1::{
|
|
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
|
|
CoreState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
|
Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes,
|
|
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
|
};
|
|
use runtime_common::{
|
|
auctions, claims, crowdloan, impls::DealWithFees, paras_registrar, slots, xcm_sender,
|
|
BlockHashCount, BlockLength, BlockWeights, CurrencyToVote, OffchainSolutionLengthLimit,
|
|
OffchainSolutionWeightLimit, RocksDbWeight, SlowAdjustingFeeUpdate, ToAuthor,
|
|
};
|
|
use sp_core::u32_trait::{_1, _2, _3, _5};
|
|
use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*};
|
|
|
|
use runtime_parachains::{
|
|
configuration as parachains_configuration, dmp as parachains_dmp, hrmp as parachains_hrmp,
|
|
inclusion as parachains_inclusion, initializer as parachains_initializer,
|
|
origin as parachains_origin, paras as parachains_paras,
|
|
paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
|
|
runtime_api_impl::v1 as parachains_runtime_api_impl, scheduler as parachains_scheduler,
|
|
session_info as parachains_session_info, shared as parachains_shared, ump as parachains_ump,
|
|
};
|
|
|
|
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
|
|
use beefy_primitives::crypto::AuthorityId as BeefyId;
|
|
use frame_support::{
|
|
construct_runtime, match_type, parameter_types,
|
|
traits::{
|
|
Contains, Everything, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, Nothing,
|
|
PrivilegeCmp,
|
|
},
|
|
weights::Weight,
|
|
PalletId, RuntimeDebug,
|
|
};
|
|
use frame_system::{EnsureOneOf, EnsureRoot};
|
|
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
|
|
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
|
|
use pallet_mmr_primitives as mmr;
|
|
use pallet_session::historical as session_historical;
|
|
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
|
|
use sp_arithmetic::Perquintill;
|
|
use sp_core::OpaqueMetadata;
|
|
use sp_runtime::{
|
|
create_runtime_str, generic, impl_opaque_keys,
|
|
traits::{
|
|
AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT,
|
|
OpaqueKeys, SaturatedConversion, Verify,
|
|
},
|
|
transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
|
|
ApplyExtrinsicResult, KeyTypeId, Perbill, Percent, Permill,
|
|
};
|
|
use sp_staking::SessionIndex;
|
|
#[cfg(any(feature = "std", test))]
|
|
use sp_version::NativeVersion;
|
|
use sp_version::RuntimeVersion;
|
|
use static_assertions::const_assert;
|
|
use xcm::latest::prelude::*;
|
|
use xcm_builder::{
|
|
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
|
|
AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, BackingToPlurality,
|
|
ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
|
|
CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete,
|
|
LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
|
|
TakeWeightCredit, UsingComponents,
|
|
};
|
|
use xcm_executor::XcmExecutor;
|
|
|
|
pub use pallet_balances::Call as BalancesCall;
|
|
pub use pallet_election_provider_multi_phase::Call as EPMCall;
|
|
#[cfg(feature = "std")]
|
|
pub use pallet_staking::StakerStatus;
|
|
pub use pallet_timestamp::Call as TimestampCall;
|
|
#[cfg(any(feature = "std", test))]
|
|
pub use sp_runtime::BuildStorage;
|
|
|
|
/// Constant values used within the runtime.
|
|
pub mod constants;
|
|
use constants::{currency::*, fee::*, time::*};
|
|
|
|
// Weights used in the runtime.
|
|
mod weights;
|
|
|
|
// Voter bag threshold definitions.
|
|
mod bag_thresholds;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
// Make the WASM binary available.
|
|
#[cfg(feature = "std")]
|
|
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
|
|
|
/// Runtime version (Kusama).
|
|
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|
spec_name: create_runtime_str!("kusama"),
|
|
impl_name: create_runtime_str!("parity-kusama"),
|
|
authoring_version: 2,
|
|
spec_version: 9130,
|
|
impl_version: 0,
|
|
#[cfg(not(feature = "disable-runtime-api"))]
|
|
apis: RUNTIME_API_VERSIONS,
|
|
#[cfg(feature = "disable-runtime-api")]
|
|
apis: version::create_apis_vec![[]],
|
|
transaction_version: 7,
|
|
};
|
|
|
|
/// The BABE epoch configuration at genesis.
|
|
pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration =
|
|
babe_primitives::BabeEpochConfiguration {
|
|
c: PRIMARY_PROBABILITY,
|
|
allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots,
|
|
};
|
|
|
|
/// Native version.
|
|
#[cfg(any(feature = "std", test))]
|
|
pub fn native_version() -> NativeVersion {
|
|
NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
|
|
}
|
|
|
|
/// Don't allow swaps until parathread story is more mature.
|
|
pub struct BaseFilter;
|
|
impl Contains<Call> for BaseFilter {
|
|
fn contains(c: &Call) -> bool {
|
|
!matches!(c, Call::Registrar(paras_registrar::Call::swap { .. }))
|
|
}
|
|
}
|
|
|
|
type MoreThanHalfCouncil = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>,
|
|
>;
|
|
|
|
parameter_types! {
|
|
pub const Version: RuntimeVersion = VERSION;
|
|
pub const SS58Prefix: u8 = 2;
|
|
}
|
|
|
|
impl frame_system::Config for Runtime {
|
|
type BaseCallFilter = BaseFilter;
|
|
type BlockWeights = BlockWeights;
|
|
type BlockLength = BlockLength;
|
|
type Origin = Origin;
|
|
type Call = Call;
|
|
type Index = Nonce;
|
|
type BlockNumber = BlockNumber;
|
|
type Hash = Hash;
|
|
type Hashing = BlakeTwo256;
|
|
type AccountId = AccountId;
|
|
type Lookup = AccountIdLookup<AccountId, ()>;
|
|
type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
|
type Event = Event;
|
|
type BlockHashCount = BlockHashCount;
|
|
type DbWeight = RocksDbWeight;
|
|
type Version = Version;
|
|
type PalletInfo = PalletInfo;
|
|
type AccountData = pallet_balances::AccountData<Balance>;
|
|
type OnNewAccount = ();
|
|
type OnKilledAccount = ();
|
|
type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
|
|
type SS58Prefix = SS58Prefix;
|
|
type OnSetCode = ();
|
|
}
|
|
|
|
parameter_types! {
|
|
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
|
|
BlockWeights::get().max_block;
|
|
pub const MaxScheduledPerBlock: u32 = 50;
|
|
}
|
|
|
|
type ScheduleOrigin = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>,
|
|
>;
|
|
|
|
/// Used the compare the privilege of an origin inside the scheduler.
|
|
pub struct OriginPrivilegeCmp;
|
|
|
|
impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
|
|
fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
|
|
if left == right {
|
|
return Some(Ordering::Equal)
|
|
}
|
|
|
|
match (left, right) {
|
|
// Root is greater than anything.
|
|
(OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater),
|
|
// Check which one has more yes votes.
|
|
(
|
|
OriginCaller::Council(pallet_collective::RawOrigin::Members(l_yes_votes, l_count)),
|
|
OriginCaller::Council(pallet_collective::RawOrigin::Members(r_yes_votes, r_count)),
|
|
) => Some((l_yes_votes * r_count).cmp(&(r_yes_votes * l_count))),
|
|
// For every other origin we don't care, as they are not used for `ScheduleOrigin`.
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl pallet_scheduler::Config for Runtime {
|
|
type Event = Event;
|
|
type Origin = Origin;
|
|
type PalletsOrigin = OriginCaller;
|
|
type Call = Call;
|
|
type MaximumWeight = MaximumSchedulerWeight;
|
|
type ScheduleOrigin = ScheduleOrigin;
|
|
type MaxScheduledPerBlock = MaxScheduledPerBlock;
|
|
type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
|
|
type OriginPrivilegeCmp = OriginPrivilegeCmp;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
|
|
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
|
|
pub const ReportLongevity: u64 =
|
|
BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
|
|
}
|
|
|
|
impl pallet_babe::Config for Runtime {
|
|
type EpochDuration = EpochDuration;
|
|
type ExpectedBlockTime = ExpectedBlockTime;
|
|
|
|
// session module is the trigger
|
|
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
|
|
|
|
type DisabledValidators = Session;
|
|
|
|
type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
|
|
KeyTypeId,
|
|
pallet_babe::AuthorityId,
|
|
)>>::Proof;
|
|
|
|
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
|
|
KeyTypeId,
|
|
pallet_babe::AuthorityId,
|
|
)>>::IdentificationTuple;
|
|
|
|
type KeyOwnerProofSystem = Historical;
|
|
|
|
type HandleEquivocation =
|
|
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
|
|
|
|
type WeightInfo = ();
|
|
|
|
type MaxAuthorities = MaxAuthorities;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const IndexDeposit: Balance = 100 * CENTS;
|
|
}
|
|
|
|
impl pallet_indices::Config for Runtime {
|
|
type AccountIndex = AccountIndex;
|
|
type Currency = Balances;
|
|
type Deposit = IndexDeposit;
|
|
type Event = Event;
|
|
type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const ExistentialDeposit: Balance = 1 * CENTS;
|
|
pub const MaxLocks: u32 = 50;
|
|
pub const MaxReserves: u32 = 50;
|
|
}
|
|
|
|
impl pallet_balances::Config for Runtime {
|
|
type Balance = Balance;
|
|
type DustRemoval = ();
|
|
type Event = Event;
|
|
type ExistentialDeposit = ExistentialDeposit;
|
|
type AccountStore = System;
|
|
type MaxLocks = MaxLocks;
|
|
type MaxReserves = MaxReserves;
|
|
type ReserveIdentifier = [u8; 8];
|
|
type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
|
|
/// This value increases the priority of `Operational` transactions by adding
|
|
/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
|
|
pub const OperationalFeeMultiplier: u8 = 5;
|
|
}
|
|
|
|
impl pallet_transaction_payment::Config for Runtime {
|
|
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Self>>;
|
|
type TransactionByteFee = TransactionByteFee;
|
|
type OperationalFeeMultiplier = OperationalFeeMultiplier;
|
|
type WeightToFee = WeightToFee;
|
|
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
|
}
|
|
impl pallet_timestamp::Config for Runtime {
|
|
type Moment = u64;
|
|
type OnTimestampSet = Babe;
|
|
type MinimumPeriod = MinimumPeriod;
|
|
type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const UncleGenerations: u32 = 0;
|
|
}
|
|
|
|
impl pallet_authorship::Config for Runtime {
|
|
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
|
|
type UncleGenerations = UncleGenerations;
|
|
type FilterUncle = ();
|
|
type EventHandler = (Staking, ImOnline);
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const Period: BlockNumber = 10 * MINUTES;
|
|
pub const Offset: BlockNumber = 0;
|
|
}
|
|
|
|
impl_opaque_keys! {
|
|
pub struct SessionKeys {
|
|
pub grandpa: Grandpa,
|
|
pub babe: Babe,
|
|
pub im_online: ImOnline,
|
|
pub para_validator: Initializer,
|
|
pub para_assignment: ParaSessionInfo,
|
|
pub authority_discovery: AuthorityDiscovery,
|
|
}
|
|
}
|
|
|
|
impl pallet_session::Config for Runtime {
|
|
type Event = Event;
|
|
type ValidatorId = AccountId;
|
|
type ValidatorIdOf = pallet_staking::StashOf<Self>;
|
|
type ShouldEndSession = Babe;
|
|
type NextSessionRotation = Babe;
|
|
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
|
|
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
|
|
type Keys = SessionKeys;
|
|
type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
|
|
}
|
|
|
|
impl pallet_session::historical::Config for Runtime {
|
|
type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
|
|
type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
// phase durations. 1/4 of the last session for each.
|
|
pub const SignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
|
|
pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
|
|
|
|
// signed config
|
|
pub const SignedMaxSubmissions: u32 = 16;
|
|
pub const SignedDepositBase: Balance = deposit(2, 0);
|
|
pub const SignedDepositByte: Balance = deposit(0, 10) / 1024;
|
|
// Each good submission will get 1/10 KSM as reward
|
|
pub SignedRewardBase: Balance = UNITS / 10;
|
|
pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(5u32, 10_000);
|
|
|
|
// 1 hour session, 15 minutes unsigned phase, 8 offchain executions.
|
|
pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 8;
|
|
|
|
/// Whilst `UseNominatorsAndUpdateBagsList` or `UseNominatorsMap` is in use, this can still be a
|
|
/// very large value. Once the `BagsList` is in full motion, staking might open its door to many
|
|
/// more nominators, and this value should instead be what is a "safe" number (e.g. 22500).
|
|
pub const VoterSnapshotPerBlock: u32 = 22_500;
|
|
}
|
|
|
|
sp_npos_elections::generate_solution_type!(
|
|
#[compact]
|
|
pub struct NposCompactSolution24::<
|
|
VoterIndex = u32,
|
|
TargetIndex = u16,
|
|
Accuracy = sp_runtime::PerU16,
|
|
>(24)
|
|
);
|
|
|
|
impl pallet_election_provider_multi_phase::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type EstimateCallFee = TransactionPayment;
|
|
type UnsignedPhase = UnsignedPhase;
|
|
type SignedMaxSubmissions = SignedMaxSubmissions;
|
|
type SignedRewardBase = SignedRewardBase;
|
|
type SignedDepositBase = SignedDepositBase;
|
|
type SignedDepositByte = SignedDepositByte;
|
|
type SignedDepositWeight = ();
|
|
type SignedMaxWeight = Self::MinerMaxWeight;
|
|
type SlashHandler = (); // burn slashes
|
|
type RewardHandler = (); // nothing to do upon rewards
|
|
type SignedPhase = SignedPhase;
|
|
type SolutionImprovementThreshold = SolutionImprovementThreshold;
|
|
type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
|
|
type MinerMaxLength = OffchainSolutionLengthLimit;
|
|
type OffchainRepeat = OffchainRepeat;
|
|
type MinerTxPriority = NposSolutionPriority;
|
|
type DataProvider = Staking;
|
|
type Solution = NposCompactSolution24;
|
|
type Fallback = pallet_election_provider_multi_phase::NoFallback<Self>;
|
|
type Solver = frame_election_provider_support::SequentialPhragmen<
|
|
AccountId,
|
|
pallet_election_provider_multi_phase::SolutionAccuracyOf<Self>,
|
|
runtime_common::elections::OffchainRandomBalancing,
|
|
>;
|
|
type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig;
|
|
type ForceOrigin = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
|
|
>;
|
|
type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Self>;
|
|
type VoterSnapshotPerBlock = VoterSnapshotPerBlock;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS;
|
|
}
|
|
|
|
impl pallet_bags_list::Config for Runtime {
|
|
type Event = Event;
|
|
type VoteWeightProvider = Staking;
|
|
type WeightInfo = weights::pallet_bags_list::WeightInfo<Runtime>;
|
|
type BagThresholds = BagThresholds;
|
|
}
|
|
|
|
fn era_payout(
|
|
total_staked: Balance,
|
|
non_gilt_issuance: Balance,
|
|
max_annual_inflation: Perquintill,
|
|
period_fraction: Perquintill,
|
|
auctioned_slots: u64,
|
|
) -> (Balance, Balance) {
|
|
use pallet_staking_reward_fn::compute_inflation;
|
|
use sp_arithmetic::traits::Saturating;
|
|
|
|
let min_annual_inflation = Perquintill::from_rational(25u64, 1000u64);
|
|
let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation);
|
|
|
|
// 30% reserved for up to 60 slots.
|
|
let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64);
|
|
|
|
// Therefore the ideal amount at stake (as a percentage of total issuance) is 75% less the amount that we expect
|
|
// to be taken up with auctions.
|
|
let ideal_stake = Perquintill::from_percent(75).saturating_sub(auction_proportion);
|
|
|
|
let stake = Perquintill::from_rational(total_staked, non_gilt_issuance);
|
|
let falloff = Perquintill::from_percent(5);
|
|
let adjustment = compute_inflation(stake, ideal_stake, falloff);
|
|
let staking_inflation =
|
|
min_annual_inflation.saturating_add(delta_annual_inflation * adjustment);
|
|
|
|
let max_payout = period_fraction * max_annual_inflation * non_gilt_issuance;
|
|
let staking_payout = (period_fraction * staking_inflation) * non_gilt_issuance;
|
|
let rest = max_payout.saturating_sub(staking_payout);
|
|
|
|
let other_issuance = non_gilt_issuance.saturating_sub(total_staked);
|
|
if total_staked > other_issuance {
|
|
let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout;
|
|
// We don't do anything with this, but if we wanted to, we could introduce a cap on the treasury amount
|
|
// with: `rest = rest.min(cap_rest);`
|
|
}
|
|
(staking_payout, rest)
|
|
}
|
|
|
|
pub struct EraPayout;
|
|
impl pallet_staking::EraPayout<Balance> for EraPayout {
|
|
fn era_payout(
|
|
total_staked: Balance,
|
|
_total_issuance: Balance,
|
|
era_duration_millis: u64,
|
|
) -> (Balance, Balance) {
|
|
// TODO: #3011 Update with proper auctioned slots tracking.
|
|
// This should be fine for the first year of parachains.
|
|
let auctioned_slots: u64 = auctions::Pallet::<Runtime>::auction_counter().into();
|
|
const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10);
|
|
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
|
|
|
|
era_payout(
|
|
total_staked,
|
|
Gilt::issuance().non_gilt,
|
|
MAX_ANNUAL_INFLATION,
|
|
Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR),
|
|
auctioned_slots,
|
|
)
|
|
}
|
|
}
|
|
|
|
parameter_types! {
|
|
// Six sessions in an era (6 hours).
|
|
pub const SessionsPerEra: SessionIndex = 6;
|
|
// 28 eras for unbonding (7 days).
|
|
pub const BondingDuration: pallet_staking::EraIndex = 28;
|
|
// 27 eras in which slashes can be cancelled (slightly less than 7 days).
|
|
pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
|
|
pub const MaxNominatorRewardedPerValidator: u32 = 256;
|
|
pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17);
|
|
}
|
|
|
|
type SlashCancelOrigin = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>,
|
|
>;
|
|
|
|
impl frame_election_provider_support::onchain::Config for Runtime {
|
|
type Accuracy = runtime_common::elections::OnOnChainAccuracy;
|
|
type DataProvider = Staking;
|
|
}
|
|
|
|
impl pallet_staking::Config for Runtime {
|
|
const MAX_NOMINATIONS: u32 =
|
|
<NposCompactSolution24 as sp_npos_elections::NposSolution>::LIMIT as u32;
|
|
type Currency = Balances;
|
|
type UnixTime = Timestamp;
|
|
type CurrencyToVote = CurrencyToVote;
|
|
type ElectionProvider = ElectionProviderMultiPhase;
|
|
type GenesisElectionProvider = runtime_common::elections::GenesisElectionOf<Self>;
|
|
type RewardRemainder = Treasury;
|
|
type Event = Event;
|
|
type Slash = Treasury;
|
|
type Reward = ();
|
|
type SessionsPerEra = SessionsPerEra;
|
|
type BondingDuration = BondingDuration;
|
|
type SlashDeferDuration = SlashDeferDuration;
|
|
// A majority of the council or root can cancel the slash.
|
|
type SlashCancelOrigin = SlashCancelOrigin;
|
|
type SessionInterface = Self;
|
|
type EraPayout = EraPayout;
|
|
type NextNewSession = Session;
|
|
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
|
|
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
|
|
// Use the nominators map to iter voters, but also keep bags-list up-to-date.
|
|
type SortedListProvider = runtime_common::elections::UseNominatorsAndUpdateBagsList<Runtime>;
|
|
type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const LaunchPeriod: BlockNumber = 7 * DAYS;
|
|
pub const VotingPeriod: BlockNumber = 7 * DAYS;
|
|
pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
|
|
pub const MinimumDeposit: Balance = 100 * CENTS;
|
|
pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
|
|
pub const CooloffPeriod: BlockNumber = 7 * DAYS;
|
|
// One cent: $10,000 / MB
|
|
pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
|
|
pub const InstantAllowed: bool = true;
|
|
pub const MaxVotes: u32 = 100;
|
|
pub const MaxProposals: u32 = 100;
|
|
}
|
|
|
|
impl pallet_democracy::Config for Runtime {
|
|
type Proposal = Call;
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type EnactmentPeriod = EnactmentPeriod;
|
|
type VoteLockingPeriod = EnactmentPeriod;
|
|
type LaunchPeriod = LaunchPeriod;
|
|
type VotingPeriod = VotingPeriod;
|
|
type MinimumDeposit = MinimumDeposit;
|
|
/// A straight majority of the council can decide what their next motion is.
|
|
type ExternalOrigin =
|
|
pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
|
|
/// A majority can have the next scheduled referendum be a straight majority-carries vote.
|
|
type ExternalMajorityOrigin =
|
|
pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
|
|
/// A unanimous council can have the next scheduled referendum be a straight default-carries
|
|
/// (NTB) vote.
|
|
type ExternalDefaultOrigin =
|
|
pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
|
|
/// Two thirds of the technical committee can have an `ExternalMajority/ExternalDefault` vote
|
|
/// be tabled immediately and with a shorter voting/enactment period.
|
|
type FastTrackOrigin =
|
|
pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
|
|
type InstantOrigin =
|
|
pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
|
|
type InstantAllowed = InstantAllowed;
|
|
type FastTrackVotingPeriod = FastTrackVotingPeriod;
|
|
// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
|
|
type CancellationOrigin = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
|
|
>;
|
|
type BlacklistOrigin = EnsureRoot<AccountId>;
|
|
// To cancel a proposal before it has been passed, the technical committee must be unanimous or
|
|
// Root must agree.
|
|
type CancelProposalOrigin = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
|
|
>;
|
|
// Any single technical committee member may veto a coming council proposal, however they can
|
|
// only do it once and it lasts only for the cooloff period.
|
|
type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
|
|
type CooloffPeriod = CooloffPeriod;
|
|
type PreimageByteDeposit = PreimageByteDeposit;
|
|
type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
|
|
type Slash = Treasury;
|
|
type Scheduler = Scheduler;
|
|
type PalletsOrigin = OriginCaller;
|
|
type MaxVotes = MaxVotes;
|
|
type WeightInfo = weights::pallet_democracy::WeightInfo<Runtime>;
|
|
type MaxProposals = MaxProposals;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
|
|
pub const CouncilMaxProposals: u32 = 100;
|
|
pub const CouncilMaxMembers: u32 = 100;
|
|
}
|
|
|
|
type CouncilCollective = pallet_collective::Instance1;
|
|
impl pallet_collective::Config<CouncilCollective> for Runtime {
|
|
type Origin = Origin;
|
|
type Proposal = Call;
|
|
type Event = Event;
|
|
type MotionDuration = CouncilMotionDuration;
|
|
type MaxProposals = CouncilMaxProposals;
|
|
type MaxMembers = CouncilMaxMembers;
|
|
type DefaultVote = pallet_collective::PrimeDefaultVote;
|
|
type WeightInfo = weights::pallet_collective_council::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const CandidacyBond: Balance = 100 * CENTS;
|
|
// 1 storage item created, key size is 32 bytes, value size is 16+16.
|
|
pub const VotingBondBase: Balance = deposit(1, 64);
|
|
// additional data per vote is 32 bytes (account id).
|
|
pub const VotingBondFactor: Balance = deposit(0, 32);
|
|
/// Daily council elections
|
|
pub const TermDuration: BlockNumber = 24 * HOURS;
|
|
pub const DesiredMembers: u32 = 19;
|
|
pub const DesiredRunnersUp: u32 = 19;
|
|
pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect";
|
|
}
|
|
|
|
// Make sure that there are no more than MaxMembers members elected via phragmen.
|
|
const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
|
|
|
|
impl pallet_elections_phragmen::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type ChangeMembers = Council;
|
|
type InitializeMembers = Council;
|
|
type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
|
|
type CandidacyBond = CandidacyBond;
|
|
type VotingBondBase = VotingBondBase;
|
|
type VotingBondFactor = VotingBondFactor;
|
|
type LoserCandidate = Treasury;
|
|
type KickedMember = Treasury;
|
|
type DesiredMembers = DesiredMembers;
|
|
type DesiredRunnersUp = DesiredRunnersUp;
|
|
type TermDuration = TermDuration;
|
|
type PalletId = PhragmenElectionPalletId;
|
|
type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
|
|
pub const TechnicalMaxProposals: u32 = 100;
|
|
pub const TechnicalMaxMembers: u32 = 100;
|
|
}
|
|
|
|
type TechnicalCollective = pallet_collective::Instance2;
|
|
impl pallet_collective::Config<TechnicalCollective> for Runtime {
|
|
type Origin = Origin;
|
|
type Proposal = Call;
|
|
type Event = Event;
|
|
type MotionDuration = TechnicalMotionDuration;
|
|
type MaxProposals = TechnicalMaxProposals;
|
|
type MaxMembers = TechnicalMaxMembers;
|
|
type DefaultVote = pallet_collective::PrimeDefaultVote;
|
|
type WeightInfo = weights::pallet_collective_technical_committee::WeightInfo<Runtime>;
|
|
}
|
|
|
|
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
|
|
type Event = Event;
|
|
type AddOrigin = MoreThanHalfCouncil;
|
|
type RemoveOrigin = MoreThanHalfCouncil;
|
|
type SwapOrigin = MoreThanHalfCouncil;
|
|
type ResetOrigin = MoreThanHalfCouncil;
|
|
type PrimeOrigin = MoreThanHalfCouncil;
|
|
type MembershipInitialized = TechnicalCommittee;
|
|
type MembershipChanged = TechnicalCommittee;
|
|
type MaxMembers = TechnicalMaxMembers;
|
|
type WeightInfo = weights::pallet_membership::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const ProposalBond: Permill = Permill::from_percent(5);
|
|
pub const ProposalBondMinimum: Balance = 2000 * CENTS;
|
|
pub const SpendPeriod: BlockNumber = 6 * DAYS;
|
|
pub const Burn: Permill = Permill::from_perthousand(2);
|
|
pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
|
|
|
|
pub const TipCountdown: BlockNumber = 1 * DAYS;
|
|
pub const TipFindersFee: Percent = Percent::from_percent(20);
|
|
pub const TipReportDepositBase: Balance = 100 * CENTS;
|
|
pub const DataDepositPerByte: Balance = 1 * CENTS;
|
|
pub const BountyDepositBase: Balance = 100 * CENTS;
|
|
pub const BountyDepositPayoutDelay: BlockNumber = 4 * DAYS;
|
|
pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS;
|
|
pub const MaximumReasonLength: u32 = 16384;
|
|
pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
|
|
pub const BountyValueMinimum: Balance = 200 * CENTS;
|
|
pub const MaxApprovals: u32 = 100;
|
|
pub const MaxAuthorities: u32 = 100_000;
|
|
pub const MaxKeys: u32 = 10_000;
|
|
pub const MaxPeerInHeartbeats: u32 = 10_000;
|
|
pub const MaxPeerDataEncodingSize: u32 = 1_000;
|
|
}
|
|
|
|
type ApproveOrigin = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>,
|
|
>;
|
|
|
|
impl pallet_treasury::Config for Runtime {
|
|
type PalletId = TreasuryPalletId;
|
|
type Currency = Balances;
|
|
type ApproveOrigin = ApproveOrigin;
|
|
type RejectOrigin = MoreThanHalfCouncil;
|
|
type Event = Event;
|
|
type OnSlash = Treasury;
|
|
type ProposalBond = ProposalBond;
|
|
type ProposalBondMinimum = ProposalBondMinimum;
|
|
type SpendPeriod = SpendPeriod;
|
|
type Burn = Burn;
|
|
type BurnDestination = Society;
|
|
type MaxApprovals = MaxApprovals;
|
|
type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
|
|
type SpendFunds = Bounties;
|
|
}
|
|
|
|
impl pallet_bounties::Config for Runtime {
|
|
type BountyDepositBase = BountyDepositBase;
|
|
type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
|
|
type BountyUpdatePeriod = BountyUpdatePeriod;
|
|
type BountyCuratorDeposit = BountyCuratorDeposit;
|
|
type BountyValueMinimum = BountyValueMinimum;
|
|
type DataDepositPerByte = DataDepositPerByte;
|
|
type Event = Event;
|
|
type MaximumReasonLength = MaximumReasonLength;
|
|
type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
|
|
}
|
|
|
|
impl pallet_tips::Config for Runtime {
|
|
type MaximumReasonLength = MaximumReasonLength;
|
|
type DataDepositPerByte = DataDepositPerByte;
|
|
type Tippers = PhragmenElection;
|
|
type TipCountdown = TipCountdown;
|
|
type TipFindersFee = TipFindersFee;
|
|
type TipReportDepositBase = TipReportDepositBase;
|
|
type Event = Event;
|
|
type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
|
|
}
|
|
|
|
impl pallet_offences::Config for Runtime {
|
|
type Event = Event;
|
|
type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
|
|
type OnOffenceHandler = Staking;
|
|
}
|
|
|
|
impl pallet_authority_discovery::Config for Runtime {
|
|
type MaxAuthorities = MaxAuthorities;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub NposSolutionPriority: TransactionPriority =
|
|
Perbill::from_percent(90) * TransactionPriority::max_value();
|
|
pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
|
|
}
|
|
|
|
impl pallet_im_online::Config for Runtime {
|
|
type AuthorityId = ImOnlineId;
|
|
type Event = Event;
|
|
type ValidatorSet = Historical;
|
|
type NextSessionRotation = Babe;
|
|
type ReportUnresponsiveness = Offences;
|
|
type UnsignedPriority = ImOnlineUnsignedPriority;
|
|
type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
|
|
type MaxKeys = MaxKeys;
|
|
type MaxPeerInHeartbeats = MaxPeerInHeartbeats;
|
|
type MaxPeerDataEncodingSize = MaxPeerDataEncodingSize;
|
|
}
|
|
|
|
impl pallet_grandpa::Config for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
|
|
type KeyOwnerProof =
|
|
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
|
|
|
|
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
|
|
KeyTypeId,
|
|
GrandpaId,
|
|
)>>::IdentificationTuple;
|
|
|
|
type KeyOwnerProofSystem = Historical;
|
|
|
|
type HandleEquivocation = pallet_grandpa::EquivocationHandler<
|
|
Self::KeyOwnerIdentification,
|
|
Offences,
|
|
ReportLongevity,
|
|
>;
|
|
|
|
type WeightInfo = ();
|
|
type MaxAuthorities = MaxAuthorities;
|
|
}
|
|
|
|
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
|
|
/// format of the chain.
|
|
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
|
|
where
|
|
Call: From<LocalCall>,
|
|
{
|
|
fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
|
|
call: Call,
|
|
public: <Signature as Verify>::Signer,
|
|
account: AccountId,
|
|
nonce: <Runtime as frame_system::Config>::Index,
|
|
) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
|
|
use sp_runtime::traits::StaticLookup;
|
|
// take the biggest period possible.
|
|
let period =
|
|
BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
|
|
|
|
let current_block = System::block_number()
|
|
.saturated_into::<u64>()
|
|
// The `System::block_number` is initialized with `n+1`,
|
|
// so the actual block number is `n`.
|
|
.saturating_sub(1);
|
|
let tip = 0;
|
|
let extra: SignedExtra = (
|
|
frame_system::CheckSpecVersion::<Runtime>::new(),
|
|
frame_system::CheckTxVersion::<Runtime>::new(),
|
|
frame_system::CheckGenesis::<Runtime>::new(),
|
|
frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
|
|
period,
|
|
current_block,
|
|
)),
|
|
frame_system::CheckNonce::<Runtime>::from(nonce),
|
|
frame_system::CheckWeight::<Runtime>::new(),
|
|
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
|
|
);
|
|
let raw_payload = SignedPayload::new(call, extra)
|
|
.map_err(|e| {
|
|
log::warn!("Unable to create signed payload: {:?}", e);
|
|
})
|
|
.ok()?;
|
|
let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
|
|
let (call, extra, _) = raw_payload.deconstruct();
|
|
let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
|
|
Some((call, (address, signature, extra)))
|
|
}
|
|
}
|
|
|
|
impl frame_system::offchain::SigningTypes for Runtime {
|
|
type Public = <Signature as Verify>::Signer;
|
|
type Signature = Signature;
|
|
}
|
|
|
|
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
|
|
where
|
|
Call: From<C>,
|
|
{
|
|
type Extrinsic = UncheckedExtrinsic;
|
|
type OverarchingCall = Call;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
|
|
}
|
|
|
|
impl claims::Config for Runtime {
|
|
type Event = Event;
|
|
type VestingSchedule = Vesting;
|
|
type Prefix = Prefix;
|
|
type MoveClaimOrigin =
|
|
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
|
|
type WeightInfo = weights::runtime_common_claims::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
// Minimum 100 bytes/KSM deposited (1 CENT/byte)
|
|
pub const BasicDeposit: Balance = 1000 * CENTS; // 258 bytes on-chain
|
|
pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain
|
|
pub const SubAccountDeposit: Balance = 200 * CENTS; // 53 bytes on-chain
|
|
pub const MaxSubAccounts: u32 = 100;
|
|
pub const MaxAdditionalFields: u32 = 100;
|
|
pub const MaxRegistrars: u32 = 20;
|
|
}
|
|
|
|
impl pallet_identity::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type BasicDeposit = BasicDeposit;
|
|
type FieldDeposit = FieldDeposit;
|
|
type SubAccountDeposit = SubAccountDeposit;
|
|
type MaxSubAccounts = MaxSubAccounts;
|
|
type MaxAdditionalFields = MaxAdditionalFields;
|
|
type MaxRegistrars = MaxRegistrars;
|
|
type Slashed = Treasury;
|
|
type ForceOrigin = MoreThanHalfCouncil;
|
|
type RegistrarOrigin = MoreThanHalfCouncil;
|
|
type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
|
|
}
|
|
|
|
impl pallet_utility::Config for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
|
|
pub const DepositBase: Balance = deposit(1, 88);
|
|
// Additional storage item size of 32 bytes.
|
|
pub const DepositFactor: Balance = deposit(0, 32);
|
|
pub const MaxSignatories: u16 = 100;
|
|
}
|
|
|
|
impl pallet_multisig::Config for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
type Currency = Balances;
|
|
type DepositBase = DepositBase;
|
|
type DepositFactor = DepositFactor;
|
|
type MaxSignatories = MaxSignatories;
|
|
type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const ConfigDepositBase: Balance = 500 * CENTS;
|
|
pub const FriendDepositFactor: Balance = 50 * CENTS;
|
|
pub const MaxFriends: u16 = 9;
|
|
pub const RecoveryDeposit: Balance = 500 * CENTS;
|
|
}
|
|
|
|
impl pallet_recovery::Config for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
type Currency = Balances;
|
|
type ConfigDepositBase = ConfigDepositBase;
|
|
type FriendDepositFactor = FriendDepositFactor;
|
|
type MaxFriends = MaxFriends;
|
|
type RecoveryDeposit = RecoveryDeposit;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const CandidateDeposit: Balance = 1000 * CENTS;
|
|
pub const WrongSideDeduction: Balance = 200 * CENTS;
|
|
pub const MaxStrikes: u32 = 10;
|
|
pub const RotationPeriod: BlockNumber = 7 * DAYS;
|
|
pub const PeriodSpend: Balance = 50000 * CENTS;
|
|
pub const MaxLockDuration: BlockNumber = 36 * 30 * DAYS;
|
|
pub const ChallengePeriod: BlockNumber = 7 * DAYS;
|
|
pub const MaxCandidateIntake: u32 = 1;
|
|
pub const SocietyPalletId: PalletId = PalletId(*b"py/socie");
|
|
}
|
|
|
|
impl pallet_society::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
|
|
type CandidateDeposit = CandidateDeposit;
|
|
type WrongSideDeduction = WrongSideDeduction;
|
|
type MaxStrikes = MaxStrikes;
|
|
type PeriodSpend = PeriodSpend;
|
|
type MembershipChanged = ();
|
|
type RotationPeriod = RotationPeriod;
|
|
type MaxLockDuration = MaxLockDuration;
|
|
type FounderSetOrigin =
|
|
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
|
|
type SuspensionJudgementOrigin = pallet_society::EnsureFounder<Runtime>;
|
|
type ChallengePeriod = ChallengePeriod;
|
|
type MaxCandidateIntake = MaxCandidateIntake;
|
|
type PalletId = SocietyPalletId;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const MinVestedTransfer: Balance = 100 * CENTS;
|
|
}
|
|
|
|
impl pallet_vesting::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type BlockNumberToBalance = ConvertInto;
|
|
type MinVestedTransfer = MinVestedTransfer;
|
|
type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
|
|
const MAX_VESTING_SCHEDULES: u32 = 28;
|
|
}
|
|
|
|
parameter_types! {
|
|
// One storage item; key size 32, value size 8; .
|
|
pub const ProxyDepositBase: Balance = deposit(1, 8);
|
|
// Additional storage item size of 33 bytes.
|
|
pub const ProxyDepositFactor: Balance = deposit(0, 33);
|
|
pub const MaxProxies: u16 = 32;
|
|
pub const AnnouncementDepositBase: Balance = deposit(1, 8);
|
|
pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
|
|
pub const MaxPending: u16 = 32;
|
|
}
|
|
|
|
/// The type used to represent the kinds of proxying allowed.
|
|
#[derive(
|
|
Copy,
|
|
Clone,
|
|
Eq,
|
|
PartialEq,
|
|
Ord,
|
|
PartialOrd,
|
|
Encode,
|
|
Decode,
|
|
RuntimeDebug,
|
|
MaxEncodedLen,
|
|
scale_info::TypeInfo,
|
|
)]
|
|
pub enum ProxyType {
|
|
Any,
|
|
NonTransfer,
|
|
Governance,
|
|
Staking,
|
|
IdentityJudgement,
|
|
CancelProxy,
|
|
Auction,
|
|
}
|
|
impl Default for ProxyType {
|
|
fn default() -> Self {
|
|
Self::Any
|
|
}
|
|
}
|
|
impl InstanceFilter<Call> for ProxyType {
|
|
fn filter(&self, c: &Call) -> bool {
|
|
match self {
|
|
ProxyType::Any => true,
|
|
ProxyType::NonTransfer => matches!(
|
|
c,
|
|
Call::System(..) |
|
|
Call::Babe(..) |
|
|
Call::Timestamp(..) |
|
|
Call::Indices(pallet_indices::Call::claim {..}) |
|
|
Call::Indices(pallet_indices::Call::free {..}) |
|
|
Call::Indices(pallet_indices::Call::freeze {..}) |
|
|
// Specifically omitting Indices `transfer`, `force_transfer`
|
|
// Specifically omitting the entire Balances pallet
|
|
Call::Authorship(..) |
|
|
Call::Staking(..) |
|
|
Call::Session(..) |
|
|
Call::Grandpa(..) |
|
|
Call::ImOnline(..) |
|
|
Call::Democracy(..) |
|
|
Call::Council(..) |
|
|
Call::TechnicalCommittee(..) |
|
|
Call::PhragmenElection(..) |
|
|
Call::TechnicalMembership(..) |
|
|
Call::Treasury(..) |
|
|
Call::Bounties(..) |
|
|
Call::Tips(..) |
|
|
Call::Claims(..) |
|
|
Call::Utility(..) |
|
|
Call::Identity(..) |
|
|
Call::Society(..) |
|
|
Call::Recovery(pallet_recovery::Call::as_recovered {..}) |
|
|
Call::Recovery(pallet_recovery::Call::vouch_recovery {..}) |
|
|
Call::Recovery(pallet_recovery::Call::claim_recovery {..}) |
|
|
Call::Recovery(pallet_recovery::Call::close_recovery {..}) |
|
|
Call::Recovery(pallet_recovery::Call::remove_recovery {..}) |
|
|
Call::Recovery(pallet_recovery::Call::cancel_recovered {..}) |
|
|
// Specifically omitting Recovery `create_recovery`, `initiate_recovery`
|
|
Call::Vesting(pallet_vesting::Call::vest {..}) |
|
|
Call::Vesting(pallet_vesting::Call::vest_other {..}) |
|
|
// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
|
|
Call::Scheduler(..) |
|
|
Call::Proxy(..) |
|
|
Call::Multisig(..) |
|
|
Call::Gilt(..) |
|
|
Call::Registrar(paras_registrar::Call::register {..}) |
|
|
Call::Registrar(paras_registrar::Call::deregister {..}) |
|
|
// Specifically omitting Registrar `swap`
|
|
Call::Registrar(paras_registrar::Call::reserve {..}) |
|
|
Call::Crowdloan(..) |
|
|
Call::Slots(..) |
|
|
Call::Auctions(..) | // Specifically omitting the entire XCM Pallet
|
|
Call::BagsList(..)
|
|
),
|
|
ProxyType::Governance => matches!(
|
|
c,
|
|
Call::Democracy(..) |
|
|
Call::Council(..) | Call::TechnicalCommittee(..) |
|
|
Call::PhragmenElection(..) |
|
|
Call::Treasury(..) | Call::Bounties(..) |
|
|
Call::Tips(..) | Call::Utility(..)
|
|
),
|
|
ProxyType::Staking => {
|
|
matches!(c, Call::Staking(..) | Call::Session(..) | Call::Utility(..))
|
|
},
|
|
ProxyType::IdentityJudgement => matches!(
|
|
c,
|
|
Call::Identity(pallet_identity::Call::provide_judgement { .. }) | Call::Utility(..)
|
|
),
|
|
ProxyType::CancelProxy => {
|
|
matches!(c, Call::Proxy(pallet_proxy::Call::reject_announcement { .. }))
|
|
},
|
|
ProxyType::Auction => matches!(
|
|
c,
|
|
Call::Auctions(..) | Call::Crowdloan(..) | Call::Registrar(..) | Call::Slots(..)
|
|
),
|
|
}
|
|
}
|
|
fn is_superset(&self, o: &Self) -> bool {
|
|
match (self, o) {
|
|
(x, y) if x == y => true,
|
|
(ProxyType::Any, _) => true,
|
|
(_, ProxyType::Any) => false,
|
|
(ProxyType::NonTransfer, _) => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl pallet_proxy::Config for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
type Currency = Balances;
|
|
type ProxyType = ProxyType;
|
|
type ProxyDepositBase = ProxyDepositBase;
|
|
type ProxyDepositFactor = ProxyDepositFactor;
|
|
type MaxProxies = MaxProxies;
|
|
type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
|
|
type MaxPending = MaxPending;
|
|
type CallHasher = BlakeTwo256;
|
|
type AnnouncementDepositBase = AnnouncementDepositBase;
|
|
type AnnouncementDepositFactor = AnnouncementDepositFactor;
|
|
}
|
|
|
|
impl parachains_origin::Config for Runtime {}
|
|
|
|
impl parachains_configuration::Config for Runtime {
|
|
type WeightInfo = weights::runtime_parachains_configuration::WeightInfo<Runtime>;
|
|
}
|
|
|
|
impl parachains_shared::Config for Runtime {}
|
|
|
|
impl parachains_session_info::Config for Runtime {}
|
|
|
|
impl parachains_inclusion::Config for Runtime {
|
|
type Event = Event;
|
|
type DisputesHandler = ();
|
|
type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints<Runtime>;
|
|
}
|
|
|
|
impl parachains_paras::Config for Runtime {
|
|
type Origin = Origin;
|
|
type Event = Event;
|
|
type WeightInfo = weights::runtime_parachains_paras::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const FirstMessageFactorPercent: u64 = 100;
|
|
}
|
|
|
|
impl parachains_ump::Config for Runtime {
|
|
type Event = Event;
|
|
type UmpSink = crate::parachains_ump::XcmSink<XcmExecutor<XcmConfig>, Runtime>;
|
|
type FirstMessageFactorPercent = FirstMessageFactorPercent;
|
|
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
|
|
}
|
|
|
|
impl parachains_dmp::Config for Runtime {}
|
|
|
|
impl parachains_hrmp::Config for Runtime {
|
|
type Event = Event;
|
|
type Origin = Origin;
|
|
type Currency = Balances;
|
|
}
|
|
|
|
impl parachains_paras_inherent::Config for Runtime {}
|
|
|
|
impl parachains_scheduler::Config for Runtime {}
|
|
|
|
impl parachains_initializer::Config for Runtime {
|
|
type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
|
|
type ForceOrigin = EnsureRoot<AccountId>;
|
|
type WeightInfo = weights::runtime_parachains_initializer::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const ParaDeposit: Balance = 40 * UNITS;
|
|
}
|
|
|
|
impl paras_registrar::Config for Runtime {
|
|
type Event = Event;
|
|
type Origin = Origin;
|
|
type Currency = Balances;
|
|
type OnSwap = (Crowdloan, Slots);
|
|
type ParaDeposit = ParaDeposit;
|
|
type DataDepositPerByte = DataDepositPerByte;
|
|
type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
// 6 weeks
|
|
pub const LeasePeriod: BlockNumber = 6 * WEEKS;
|
|
}
|
|
|
|
impl slots::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type Registrar = Registrar;
|
|
type LeasePeriod = LeasePeriod;
|
|
type LeaseOffset = ();
|
|
type WeightInfo = weights::runtime_common_slots::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
|
|
pub const SubmissionDeposit: Balance = 3 * GRAND; // ~ 10 KSM
|
|
pub const MinContribution: Balance = 3_000 * CENTS; // ~ .1 KSM
|
|
pub const RemoveKeysLimit: u32 = 1000;
|
|
// Allow 32 bytes for an additional memo to a crowdloan.
|
|
pub const MaxMemoLength: u8 = 32;
|
|
}
|
|
|
|
impl crowdloan::Config for Runtime {
|
|
type Event = Event;
|
|
type PalletId = CrowdloanId;
|
|
type SubmissionDeposit = SubmissionDeposit;
|
|
type MinContribution = MinContribution;
|
|
type RemoveKeysLimit = RemoveKeysLimit;
|
|
type Registrar = Registrar;
|
|
type Auctioneer = Auctions;
|
|
type MaxMemoLength = MaxMemoLength;
|
|
type WeightInfo = weights::runtime_common_crowdloan::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
// The average auction is 7 days long, so this will be 70% for ending period.
|
|
// 5 Days = 72000 Blocks @ 6 sec per block
|
|
pub const EndingPeriod: BlockNumber = 5 * DAYS;
|
|
// ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples
|
|
pub const SampleLength: BlockNumber = 2 * MINUTES;
|
|
}
|
|
|
|
type AuctionInitiate = EnsureOneOf<
|
|
AccountId,
|
|
EnsureRoot<AccountId>,
|
|
pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
|
|
>;
|
|
|
|
impl auctions::Config for Runtime {
|
|
type Event = Event;
|
|
type Leaser = Slots;
|
|
type Registrar = Registrar;
|
|
type EndingPeriod = EndingPeriod;
|
|
type SampleLength = SampleLength;
|
|
type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
|
|
type InitiateOrigin = AuctionInitiate;
|
|
type WeightInfo = weights::runtime_common_auctions::WeightInfo<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
/// The location of the KSM token, from the context of this chain. Since this token is native to this
|
|
/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
|
|
/// the context".
|
|
pub const KsmLocation: MultiLocation = Here.into();
|
|
/// The Kusama network ID. This is named.
|
|
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
|
|
/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
|
|
/// Kusama is a top-level relay-chain, there is no ancestry.
|
|
pub const Ancestry: MultiLocation = Here.into();
|
|
/// The check account, which holds any native assets that have been teleported out and not back in (yet).
|
|
pub CheckAccount: AccountId = XcmPallet::check_account();
|
|
}
|
|
|
|
/// The canonical means of converting a `MultiLocation` into an `AccountId`, used when we want to determine
|
|
/// the sovereign account controlled by a location.
|
|
pub type SovereignAccountOf = (
|
|
// We can convert a child parachain using the standard `AccountId` conversion.
|
|
ChildParachainConvertsVia<ParaId, AccountId>,
|
|
// We can directly alias an `AccountId32` into a local account.
|
|
AccountId32Aliases<KusamaNetwork, AccountId>,
|
|
);
|
|
|
|
/// Our asset transactor. This is what allows us to interest with the runtime facilities from the point of
|
|
/// view of XCM-only concepts like `MultiLocation` and `MultiAsset`.
|
|
///
|
|
/// Ours is only aware of the Balances pallet, which is mapped to `KsmLocation`.
|
|
pub type LocalAssetTransactor = XcmCurrencyAdapter<
|
|
// Use this currency:
|
|
Balances,
|
|
// Use this currency when it is a fungible asset matching the given location or name:
|
|
IsConcrete<KsmLocation>,
|
|
// We can convert the MultiLocations with our converter above:
|
|
SovereignAccountOf,
|
|
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
|
AccountId,
|
|
// We track our teleports in/out to keep total issuance correct.
|
|
CheckAccount,
|
|
>;
|
|
|
|
/// The means that we convert an the XCM message origin location into a local dispatch origin.
|
|
type LocalOriginConverter = (
|
|
// A `Signed` origin of the sovereign account that the original location controls.
|
|
SovereignSignedViaLocation<SovereignAccountOf, Origin>,
|
|
// A child parachain, natively expressed, has the `Parachain` origin.
|
|
ChildParachainAsNative<parachains_origin::Origin, Origin>,
|
|
// The AccountId32 location type can be expressed natively as a `Signed` origin.
|
|
SignedAccountId32AsNative<KusamaNetwork, Origin>,
|
|
// A system child parachain, expressed as a Superuser, converts to the `Root` origin.
|
|
ChildSystemParachainAsSuperuser<ParaId, Origin>,
|
|
);
|
|
|
|
parameter_types! {
|
|
/// The amount of weight an XCM operation takes. This is a safe overestimate.
|
|
pub const BaseXcmWeight: Weight = 1_000_000_000;
|
|
/// Maximum number of instructions in a single XCM fragment. A sanity check against weight
|
|
/// calculations getting too crazy.
|
|
pub const MaxInstructions: u32 = 100;
|
|
}
|
|
|
|
/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our
|
|
/// individual routers.
|
|
pub type XcmRouter = (
|
|
// Only one router so far - use DMP to communicate with child parachains.
|
|
xcm_sender::ChildParachainRouter<Runtime, XcmPallet>,
|
|
);
|
|
|
|
parameter_types! {
|
|
pub const Kusama: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(KsmLocation::get()) });
|
|
pub const KusamaForStatemine: (MultiAssetFilter, MultiLocation) = (Kusama::get(), Parachain(1000).into());
|
|
}
|
|
pub type TrustedTeleporters = (xcm_builder::Case<KusamaForStatemine>,);
|
|
|
|
match_type! {
|
|
pub type OnlyParachains: impl Contains<MultiLocation> = {
|
|
MultiLocation { parents: 0, interior: X1(Parachain(_)) }
|
|
};
|
|
}
|
|
|
|
/// The barriers one of which must be passed for an XCM message to be executed.
|
|
pub type Barrier = (
|
|
// Weight that is paid for may be consumed.
|
|
TakeWeightCredit,
|
|
// If the message is one that immediately attemps to pay for execution, then allow it.
|
|
AllowTopLevelPaidExecutionFrom<Everything>,
|
|
// Messages coming from system parachains need not pay for execution.
|
|
AllowUnpaidExecutionFrom<IsChildSystemParachain<ParaId>>,
|
|
// Expected responses are OK.
|
|
AllowKnownQueryResponses<XcmPallet>,
|
|
// Subscriptions for version tracking are OK.
|
|
AllowSubscriptionsFrom<OnlyParachains>,
|
|
);
|
|
|
|
pub struct XcmConfig;
|
|
impl xcm_executor::Config for XcmConfig {
|
|
type Call = Call;
|
|
type XcmSender = XcmRouter;
|
|
type AssetTransactor = LocalAssetTransactor;
|
|
type OriginConverter = LocalOriginConverter;
|
|
type IsReserve = ();
|
|
type IsTeleporter = TrustedTeleporters;
|
|
type LocationInverter = LocationInverter<Ancestry>;
|
|
type Barrier = Barrier;
|
|
type Weigher = FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;
|
|
// The weight trader piggybacks on the existing transaction-fee conversion logic.
|
|
type Trader = UsingComponents<WeightToFee, KsmLocation, AccountId, Balances, ToAuthor<Runtime>>;
|
|
type ResponseHandler = XcmPallet;
|
|
type AssetTrap = XcmPallet;
|
|
type AssetClaims = XcmPallet;
|
|
type SubscriptionService = XcmPallet;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const CouncilBodyId: BodyId = BodyId::Executive;
|
|
}
|
|
|
|
/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
|
|
/// of this chain.
|
|
pub type LocalOriginToLocation = (
|
|
// We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the
|
|
// `Unit` body.
|
|
BackingToPlurality<
|
|
Origin,
|
|
pallet_collective::Origin<Runtime, CouncilCollective>,
|
|
CouncilBodyId,
|
|
>,
|
|
// And a usual Signed origin to be used in XCM as a corresponding AccountId32
|
|
SignedToAccountId32<Origin, AccountId, KusamaNetwork>,
|
|
);
|
|
impl pallet_xcm::Config for Runtime {
|
|
type Event = Event;
|
|
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
|
type XcmRouter = XcmRouter;
|
|
// Anyone can execute XCM messages locally...
|
|
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
|
// ...but they must match our filter, which rejects all.
|
|
type XcmExecuteFilter = Nothing;
|
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
|
type XcmTeleportFilter = Everything;
|
|
type XcmReserveTransferFilter = Everything;
|
|
type Weigher = FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;
|
|
type LocationInverter = LocationInverter<Ancestry>;
|
|
type Origin = Origin;
|
|
type Call = Call;
|
|
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
|
|
type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub IgnoredIssuance: Balance = Treasury::pot();
|
|
pub const QueueCount: u32 = 300;
|
|
pub const MaxQueueLen: u32 = 1000;
|
|
pub const FifoQueueLen: u32 = 250;
|
|
pub const GiltPeriod: BlockNumber = 30 * DAYS;
|
|
pub const MinFreeze: Balance = 10_000 * CENTS;
|
|
pub const IntakePeriod: BlockNumber = 5 * MINUTES;
|
|
pub const MaxIntakeBids: u32 = 100;
|
|
}
|
|
|
|
impl pallet_gilt::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type CurrencyBalance = Balance;
|
|
type AdminOrigin = MoreThanHalfCouncil;
|
|
type Deficit = (); // Mint
|
|
type Surplus = (); // Burn
|
|
type IgnoredIssuance = IgnoredIssuance;
|
|
type QueueCount = QueueCount;
|
|
type MaxQueueLen = MaxQueueLen;
|
|
type FifoQueueLen = FifoQueueLen;
|
|
type Period = GiltPeriod;
|
|
type MinFreeze = MinFreeze;
|
|
type IntakePeriod = IntakePeriod;
|
|
type MaxIntakeBids = MaxIntakeBids;
|
|
type WeightInfo = weights::pallet_gilt::WeightInfo<Runtime>;
|
|
}
|
|
|
|
construct_runtime! {
|
|
pub enum Runtime where
|
|
Block = Block,
|
|
NodeBlock = primitives::v1::Block,
|
|
UncheckedExtrinsic = UncheckedExtrinsic
|
|
{
|
|
// Basic stuff; balances is uncallable initially.
|
|
System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 0,
|
|
|
|
// Must be before session.
|
|
Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1,
|
|
|
|
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2,
|
|
Indices: pallet_indices::{Pallet, Call, Storage, Config<T>, Event<T>} = 3,
|
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 4,
|
|
TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
|
|
|
|
// Consensus support.
|
|
Authorship: pallet_authorship::{Pallet, Call, Storage} = 5,
|
|
Staking: pallet_staking::{Pallet, Call, Storage, Config<T>, Event<T>} = 6,
|
|
Offences: pallet_offences::{Pallet, Storage, Event} = 7,
|
|
Historical: session_historical::{Pallet} = 34,
|
|
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 8,
|
|
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10,
|
|
ImOnline: pallet_im_online::{Pallet, Call, Storage, Event<T>, ValidateUnsigned, Config<T>} = 11,
|
|
AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12,
|
|
|
|
// Governance stuff; uncallable initially.
|
|
Democracy: pallet_democracy::{Pallet, Call, Storage, Config<T>, Event<T>} = 13,
|
|
Council: pallet_collective::<Instance1>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 14,
|
|
TechnicalCommittee: pallet_collective::<Instance2>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 15,
|
|
PhragmenElection: pallet_elections_phragmen::{Pallet, Call, Storage, Event<T>, Config<T>} = 16,
|
|
TechnicalMembership: pallet_membership::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 17,
|
|
Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 18,
|
|
|
|
// Claims. Usable initially.
|
|
Claims: claims::{Pallet, Call, Storage, Event<T>, Config<T>, ValidateUnsigned} = 19,
|
|
|
|
// Utility module.
|
|
Utility: pallet_utility::{Pallet, Call, Event} = 24,
|
|
|
|
// Less simple identity module.
|
|
Identity: pallet_identity::{Pallet, Call, Storage, Event<T>} = 25,
|
|
|
|
// Society module.
|
|
Society: pallet_society::{Pallet, Call, Storage, Event<T>} = 26,
|
|
|
|
// Social recovery module.
|
|
Recovery: pallet_recovery::{Pallet, Call, Storage, Event<T>} = 27,
|
|
|
|
// Vesting. Usable initially, but removed once all vesting is finished.
|
|
Vesting: pallet_vesting::{Pallet, Call, Storage, Event<T>, Config<T>} = 28,
|
|
|
|
// System scheduler.
|
|
Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>} = 29,
|
|
|
|
// Proxy module. Late addition.
|
|
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 30,
|
|
|
|
// Multisig module. Late addition.
|
|
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 31,
|
|
|
|
// Bounties module.
|
|
Bounties: pallet_bounties::{Pallet, Call, Storage, Event<T>} = 35,
|
|
|
|
// Tips module.
|
|
Tips: pallet_tips::{Pallet, Call, Storage, Event<T>} = 36,
|
|
|
|
// Election pallet. Only works with staking, but placed here to maintain indices.
|
|
ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event<T>, ValidateUnsigned} = 37,
|
|
|
|
// Gilts pallet.
|
|
Gilt: pallet_gilt::{Pallet, Call, Storage, Event<T>, Config} = 38,
|
|
|
|
// Provides a semi-sorted list of nominators for staking.
|
|
BagsList: pallet_bags_list::{Pallet, Call, Storage, Event<T>} = 39,
|
|
|
|
// Parachains pallets. Start indices at 50 to leave room.
|
|
ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50,
|
|
Configuration: parachains_configuration::{Pallet, Call, Storage, Config<T>} = 51,
|
|
ParasShared: parachains_shared::{Pallet, Call, Storage} = 52,
|
|
ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event<T>} = 53,
|
|
ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54,
|
|
ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55,
|
|
Paras: parachains_paras::{Pallet, Call, Storage, Event, Config} = 56,
|
|
Initializer: parachains_initializer::{Pallet, Call, Storage} = 57,
|
|
Dmp: parachains_dmp::{Pallet, Call, Storage} = 58,
|
|
Ump: parachains_ump::{Pallet, Call, Storage, Event} = 59,
|
|
Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event<T>} = 60,
|
|
ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61,
|
|
|
|
// Parachain Onboarding Pallets. Start indices at 70 to leave room.
|
|
Registrar: paras_registrar::{Pallet, Call, Storage, Event<T>} = 70,
|
|
Slots: slots::{Pallet, Call, Storage, Event<T>} = 71,
|
|
Auctions: auctions::{Pallet, Call, Storage, Event<T>} = 72,
|
|
Crowdloan: crowdloan::{Pallet, Call, Storage, Event<T>} = 73,
|
|
|
|
// Pallet for sending XCM.
|
|
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config} = 99,
|
|
}
|
|
}
|
|
|
|
/// The address format for describing accounts.
|
|
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
|
|
/// Block header type as expected by this runtime.
|
|
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
|
/// Block type as expected by this runtime.
|
|
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
|
/// A Block signed with a Justification
|
|
pub type SignedBlock = generic::SignedBlock<Block>;
|
|
/// `BlockId` type as expected by this runtime.
|
|
pub type BlockId = generic::BlockId<Block>;
|
|
/// The `SignedExtension` to the basic transaction logic.
|
|
pub type SignedExtra = (
|
|
frame_system::CheckSpecVersion<Runtime>,
|
|
frame_system::CheckTxVersion<Runtime>,
|
|
frame_system::CheckGenesis<Runtime>,
|
|
frame_system::CheckMortality<Runtime>,
|
|
frame_system::CheckNonce<Runtime>,
|
|
frame_system::CheckWeight<Runtime>,
|
|
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
|
|
);
|
|
/// Unchecked extrinsic type as expected by this runtime.
|
|
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
|
|
/// Executive: handles dispatch to the various modules.
|
|
pub type Executive = frame_executive::Executive<
|
|
Runtime,
|
|
Block,
|
|
frame_system::ChainContext<Runtime>,
|
|
Runtime,
|
|
AllPallets,
|
|
(),
|
|
>;
|
|
/// The payload being signed in the transactions.
|
|
pub type SignedPayload = generic::SignedPayload<Call, SignedExtra>;
|
|
|
|
#[cfg(not(feature = "disable-runtime-api"))]
|
|
sp_api::impl_runtime_apis! {
|
|
impl sp_api::Core<Block> for Runtime {
|
|
fn version() -> RuntimeVersion {
|
|
VERSION
|
|
}
|
|
|
|
fn execute_block(block: Block) {
|
|
Executive::execute_block(block);
|
|
}
|
|
|
|
fn initialize_block(header: &<Block as BlockT>::Header) {
|
|
Executive::initialize_block(header)
|
|
}
|
|
}
|
|
|
|
impl sp_api::Metadata<Block> for Runtime {
|
|
fn metadata() -> OpaqueMetadata {
|
|
OpaqueMetadata::new(Runtime::metadata().into())
|
|
}
|
|
}
|
|
|
|
impl block_builder_api::BlockBuilder<Block> for Runtime {
|
|
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
|
|
Executive::apply_extrinsic(extrinsic)
|
|
}
|
|
|
|
fn finalize_block() -> <Block as BlockT>::Header {
|
|
Executive::finalize_block()
|
|
}
|
|
|
|
fn inherent_extrinsics(data: inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
|
|
data.create_extrinsics()
|
|
}
|
|
|
|
fn check_inherents(
|
|
block: Block,
|
|
data: inherents::InherentData,
|
|
) -> inherents::CheckInherentsResult {
|
|
data.check_extrinsics(&block)
|
|
}
|
|
}
|
|
|
|
impl tx_pool_api::runtime_api::TaggedTransactionQueue<Block> for Runtime {
|
|
fn validate_transaction(
|
|
source: TransactionSource,
|
|
tx: <Block as BlockT>::Extrinsic,
|
|
block_hash: <Block as BlockT>::Hash,
|
|
) -> TransactionValidity {
|
|
Executive::validate_transaction(source, tx, block_hash)
|
|
}
|
|
}
|
|
|
|
impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
|
|
fn offchain_worker(header: &<Block as BlockT>::Header) {
|
|
Executive::offchain_worker(header)
|
|
}
|
|
}
|
|
|
|
impl primitives::v1::ParachainHost<Block, Hash, BlockNumber> for Runtime {
|
|
fn validators() -> Vec<ValidatorId> {
|
|
parachains_runtime_api_impl::validators::<Runtime>()
|
|
}
|
|
|
|
fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
|
|
parachains_runtime_api_impl::validator_groups::<Runtime>()
|
|
}
|
|
|
|
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
|
|
parachains_runtime_api_impl::availability_cores::<Runtime>()
|
|
}
|
|
|
|
fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
|
-> Option<PersistedValidationData<Hash, BlockNumber>> {
|
|
parachains_runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
|
|
}
|
|
|
|
fn assumed_validation_data(
|
|
para_id: ParaId,
|
|
expected_persisted_validation_data_hash: Hash,
|
|
) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
|
|
parachains_runtime_api_impl::assumed_validation_data::<Runtime>(
|
|
para_id,
|
|
expected_persisted_validation_data_hash,
|
|
)
|
|
}
|
|
|
|
fn check_validation_outputs(
|
|
para_id: ParaId,
|
|
outputs: primitives::v1::CandidateCommitments,
|
|
) -> bool {
|
|
parachains_runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
|
|
}
|
|
|
|
fn session_index_for_child() -> SessionIndex {
|
|
parachains_runtime_api_impl::session_index_for_child::<Runtime>()
|
|
}
|
|
|
|
fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
|
-> Option<ValidationCode> {
|
|
parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
|
|
}
|
|
|
|
fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
|
|
parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
|
|
}
|
|
|
|
fn candidate_events() -> Vec<CandidateEvent<Hash>> {
|
|
parachains_runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
|
|
match ev {
|
|
Event::ParaInclusion(ev) => {
|
|
Some(ev)
|
|
}
|
|
_ => None,
|
|
}
|
|
})
|
|
}
|
|
|
|
fn session_info(index: SessionIndex) -> Option<SessionInfo> {
|
|
parachains_runtime_api_impl::session_info::<Runtime>(index)
|
|
}
|
|
|
|
fn dmq_contents(recipient: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
|
|
parachains_runtime_api_impl::dmq_contents::<Runtime>(recipient)
|
|
}
|
|
|
|
fn inbound_hrmp_channels_contents(
|
|
recipient: ParaId
|
|
) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
|
|
parachains_runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
|
|
}
|
|
|
|
fn validation_code_by_hash(hash: ValidationCodeHash) -> Option<ValidationCode> {
|
|
parachains_runtime_api_impl::validation_code_by_hash::<Runtime>(hash)
|
|
}
|
|
|
|
fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
|
|
parachains_runtime_api_impl::on_chain_votes::<Runtime>()
|
|
}
|
|
}
|
|
|
|
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
|
fn validator_set() -> beefy_primitives::ValidatorSet<BeefyId> {
|
|
// dummy implementation due to lack of BEEFY pallet.
|
|
beefy_primitives::ValidatorSet { validators: Vec::new(), id: 0 }
|
|
}
|
|
}
|
|
|
|
impl mmr::MmrApi<Block, Hash> for Runtime {
|
|
fn generate_proof(_leaf_index: u64)
|
|
-> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof<Hash>), mmr::Error>
|
|
{
|
|
// dummy implementation due to lack of MMR pallet.
|
|
Err(mmr::Error::GenerateProof)
|
|
}
|
|
|
|
fn verify_proof(_leaf: mmr::EncodableOpaqueLeaf, _proof: mmr::Proof<Hash>)
|
|
-> Result<(), mmr::Error>
|
|
{
|
|
// dummy implementation due to lack of MMR pallet.
|
|
Err(mmr::Error::Verify)
|
|
}
|
|
|
|
fn verify_proof_stateless(
|
|
_root: Hash,
|
|
_leaf: mmr::EncodableOpaqueLeaf,
|
|
_proof: mmr::Proof<Hash>
|
|
) -> Result<(), mmr::Error> {
|
|
// dummy implementation due to lack of MMR pallet.
|
|
Err(mmr::Error::Verify)
|
|
}
|
|
}
|
|
|
|
impl fg_primitives::GrandpaApi<Block> for Runtime {
|
|
fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
|
|
Grandpa::grandpa_authorities()
|
|
}
|
|
|
|
fn current_set_id() -> fg_primitives::SetId {
|
|
Grandpa::current_set_id()
|
|
}
|
|
|
|
fn submit_report_equivocation_unsigned_extrinsic(
|
|
equivocation_proof: fg_primitives::EquivocationProof<
|
|
<Block as BlockT>::Hash,
|
|
sp_runtime::traits::NumberFor<Block>,
|
|
>,
|
|
key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
|
|
) -> Option<()> {
|
|
let key_owner_proof = key_owner_proof.decode()?;
|
|
|
|
Grandpa::submit_unsigned_equivocation_report(
|
|
equivocation_proof,
|
|
key_owner_proof,
|
|
)
|
|
}
|
|
|
|
fn generate_key_ownership_proof(
|
|
_set_id: fg_primitives::SetId,
|
|
authority_id: fg_primitives::AuthorityId,
|
|
) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
|
|
use parity_scale_codec::Encode;
|
|
|
|
Historical::prove((fg_primitives::KEY_TYPE, authority_id))
|
|
.map(|p| p.encode())
|
|
.map(fg_primitives::OpaqueKeyOwnershipProof::new)
|
|
}
|
|
}
|
|
|
|
impl babe_primitives::BabeApi<Block> for Runtime {
|
|
fn configuration() -> babe_primitives::BabeGenesisConfiguration {
|
|
// The choice of `c` parameter (where `1 - c` represents the
|
|
// probability of a slot being empty), is done in accordance to the
|
|
// slot duration and expected target block time, for safely
|
|
// resisting network delays of maximum two seconds.
|
|
// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
|
|
babe_primitives::BabeGenesisConfiguration {
|
|
slot_duration: Babe::slot_duration(),
|
|
epoch_length: EpochDuration::get(),
|
|
c: BABE_GENESIS_EPOCH_CONFIG.c,
|
|
genesis_authorities: Babe::authorities().to_vec(),
|
|
randomness: Babe::randomness(),
|
|
allowed_slots: BABE_GENESIS_EPOCH_CONFIG.allowed_slots,
|
|
}
|
|
}
|
|
|
|
fn current_epoch_start() -> babe_primitives::Slot {
|
|
Babe::current_epoch_start()
|
|
}
|
|
|
|
fn current_epoch() -> babe_primitives::Epoch {
|
|
Babe::current_epoch()
|
|
}
|
|
|
|
fn next_epoch() -> babe_primitives::Epoch {
|
|
Babe::next_epoch()
|
|
}
|
|
|
|
fn generate_key_ownership_proof(
|
|
_slot: babe_primitives::Slot,
|
|
authority_id: babe_primitives::AuthorityId,
|
|
) -> Option<babe_primitives::OpaqueKeyOwnershipProof> {
|
|
use parity_scale_codec::Encode;
|
|
|
|
Historical::prove((babe_primitives::KEY_TYPE, authority_id))
|
|
.map(|p| p.encode())
|
|
.map(babe_primitives::OpaqueKeyOwnershipProof::new)
|
|
}
|
|
|
|
fn submit_report_equivocation_unsigned_extrinsic(
|
|
equivocation_proof: babe_primitives::EquivocationProof<<Block as BlockT>::Header>,
|
|
key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof,
|
|
) -> Option<()> {
|
|
let key_owner_proof = key_owner_proof.decode()?;
|
|
|
|
Babe::submit_unsigned_equivocation_report(
|
|
equivocation_proof,
|
|
key_owner_proof,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
|
|
fn authorities() -> Vec<AuthorityDiscoveryId> {
|
|
parachains_runtime_api_impl::relevant_authority_ids::<Runtime>()
|
|
}
|
|
}
|
|
|
|
impl sp_session::SessionKeys<Block> for Runtime {
|
|
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
|
|
SessionKeys::generate(seed)
|
|
}
|
|
|
|
fn decode_session_keys(
|
|
encoded: Vec<u8>,
|
|
) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
|
|
SessionKeys::decode_into_raw_public_keys(&encoded)
|
|
}
|
|
}
|
|
|
|
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
|
|
fn account_nonce(account: AccountId) -> Nonce {
|
|
System::account_nonce(account)
|
|
}
|
|
}
|
|
|
|
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
|
|
Block,
|
|
Balance,
|
|
> for Runtime {
|
|
fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
|
|
TransactionPayment::query_info(uxt, len)
|
|
}
|
|
fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
|
|
TransactionPayment::query_fee_details(uxt, len)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "try-runtime")]
|
|
impl frame_try_runtime::TryRuntime<Block> for Runtime {
|
|
fn on_runtime_upgrade() -> (Weight, Weight) {
|
|
log::info!("try-runtime::on_runtime_upgrade kusama.");
|
|
let weight = Executive::try_runtime_upgrade().unwrap();
|
|
(weight, BlockWeights::get().max_block)
|
|
}
|
|
fn execute_block_no_check(block: Block) -> Weight {
|
|
Executive::execute_block_no_check(block)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "runtime-benchmarks")]
|
|
impl frame_benchmarking::Benchmark<Block> for Runtime {
|
|
fn benchmark_metadata(extra: bool) -> (
|
|
Vec<frame_benchmarking::BenchmarkList>,
|
|
Vec<frame_support::traits::StorageInfo>,
|
|
) {
|
|
use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};
|
|
use frame_support::traits::StorageInfoTrait;
|
|
|
|
use pallet_session_benchmarking::Pallet as SessionBench;
|
|
use pallet_offences_benchmarking::Pallet as OffencesBench;
|
|
use frame_system_benchmarking::Pallet as SystemBench;
|
|
|
|
let mut list = Vec::<BenchmarkList>::new();
|
|
|
|
// Polkadot
|
|
// NOTE: Make sure to prefix these `runtime_common::` so that path resolves correctly
|
|
// in the generated file.
|
|
list_benchmark!(list, extra, runtime_common::auctions, Auctions);
|
|
list_benchmark!(list, extra, runtime_common::crowdloan, Crowdloan);
|
|
list_benchmark!(list, extra, runtime_common::claims, Claims);
|
|
list_benchmark!(list, extra, runtime_common::slots, Slots);
|
|
list_benchmark!(list, extra, runtime_common::paras_registrar, Registrar);
|
|
list_benchmark!(list, extra, runtime_parachains::configuration, Configuration);
|
|
list_benchmark!(list, extra, runtime_parachains::initializer, Initializer);
|
|
list_benchmark!(list, extra, runtime_parachains::paras, Paras);
|
|
// Substrate
|
|
list_benchmark!(list, extra, pallet_bags_list, BagsList);
|
|
list_benchmark!(list, extra, pallet_balances, Balances);
|
|
list_benchmark!(list, extra, pallet_bounties, Bounties);
|
|
list_benchmark!(list, extra, pallet_collective, Council);
|
|
list_benchmark!(list, extra, pallet_collective, TechnicalCommittee);
|
|
list_benchmark!(list, extra, pallet_democracy, Democracy);
|
|
list_benchmark!(list, extra, pallet_elections_phragmen, PhragmenElection);
|
|
list_benchmark!(list, extra, pallet_election_provider_multi_phase, ElectionProviderMultiPhase);
|
|
list_benchmark!(list, extra, pallet_gilt, Gilt);
|
|
list_benchmark!(list, extra, pallet_identity, Identity);
|
|
list_benchmark!(list, extra, pallet_im_online, ImOnline);
|
|
list_benchmark!(list, extra, pallet_indices, Indices);
|
|
list_benchmark!(list, extra, pallet_membership, TechnicalMembership);
|
|
list_benchmark!(list, extra, pallet_multisig, Multisig);
|
|
list_benchmark!(list, extra, pallet_offences, OffencesBench::<Runtime>);
|
|
list_benchmark!(list, extra, pallet_proxy, Proxy);
|
|
list_benchmark!(list, extra, pallet_scheduler, Scheduler);
|
|
list_benchmark!(list, extra, pallet_session, SessionBench::<Runtime>);
|
|
list_benchmark!(list, extra, pallet_staking, Staking);
|
|
list_benchmark!(list, extra, frame_system, SystemBench::<Runtime>);
|
|
list_benchmark!(list, extra, pallet_timestamp, Timestamp);
|
|
list_benchmark!(list, extra, pallet_tips, Tips);
|
|
list_benchmark!(list, extra, pallet_treasury, Treasury);
|
|
list_benchmark!(list, extra, pallet_utility, Utility);
|
|
list_benchmark!(list, extra, pallet_vesting, Vesting);
|
|
|
|
let storage_info = AllPalletsWithSystem::storage_info();
|
|
|
|
return (list, storage_info)
|
|
}
|
|
|
|
fn dispatch_benchmark(
|
|
config: frame_benchmarking::BenchmarkConfig
|
|
) -> Result<
|
|
Vec<frame_benchmarking::BenchmarkBatch>,
|
|
sp_runtime::RuntimeString,
|
|
> {
|
|
use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};
|
|
// Trying to add benchmarks directly to some pallets caused cyclic dependency issues.
|
|
// To get around that, we separated the benchmarks into its own crate.
|
|
use pallet_session_benchmarking::Pallet as SessionBench;
|
|
use pallet_offences_benchmarking::Pallet as OffencesBench;
|
|
use frame_system_benchmarking::Pallet as SystemBench;
|
|
|
|
impl pallet_session_benchmarking::Config for Runtime {}
|
|
impl pallet_offences_benchmarking::Config for Runtime {}
|
|
impl frame_system_benchmarking::Config for Runtime {}
|
|
|
|
let whitelist: Vec<TrackedStorageKey> = vec![
|
|
// Block Number
|
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
|
// Total Issuance
|
|
hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
|
|
// Execution Phase
|
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),
|
|
// Event Count
|
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),
|
|
// System Events
|
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),
|
|
// Treasury Account
|
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000").to_vec().into(),
|
|
];
|
|
|
|
let mut batches = Vec::<BenchmarkBatch>::new();
|
|
let params = (&config, &whitelist);
|
|
// Polkadot
|
|
// NOTE: Make sure to prefix these `runtime_common::` so that path resolves correctly
|
|
// in the generated file.
|
|
add_benchmark!(params, batches, runtime_common::auctions, Auctions);
|
|
add_benchmark!(params, batches, runtime_common::crowdloan, Crowdloan);
|
|
add_benchmark!(params, batches, runtime_common::claims, Claims);
|
|
add_benchmark!(params, batches, runtime_common::slots, Slots);
|
|
add_benchmark!(params, batches, runtime_common::paras_registrar, Registrar);
|
|
add_benchmark!(params, batches, runtime_parachains::configuration, Configuration);
|
|
add_benchmark!(params, batches, runtime_parachains::initializer, Initializer);
|
|
add_benchmark!(params, batches, runtime_parachains::paras, Paras);
|
|
// Substrate
|
|
add_benchmark!(params, batches, pallet_balances, Balances);
|
|
add_benchmark!(params, batches, pallet_bags_list, BagsList);
|
|
add_benchmark!(params, batches, pallet_bounties, Bounties);
|
|
add_benchmark!(params, batches, pallet_collective, Council);
|
|
add_benchmark!(params, batches, pallet_collective, TechnicalCommittee);
|
|
add_benchmark!(params, batches, pallet_democracy, Democracy);
|
|
add_benchmark!(params, batches, pallet_elections_phragmen, PhragmenElection);
|
|
add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase);
|
|
add_benchmark!(params, batches, pallet_gilt, Gilt);
|
|
add_benchmark!(params, batches, pallet_identity, Identity);
|
|
add_benchmark!(params, batches, pallet_im_online, ImOnline);
|
|
add_benchmark!(params, batches, pallet_indices, Indices);
|
|
add_benchmark!(params, batches, pallet_membership, TechnicalMembership);
|
|
add_benchmark!(params, batches, pallet_multisig, Multisig);
|
|
add_benchmark!(params, batches, pallet_offences, OffencesBench::<Runtime>);
|
|
add_benchmark!(params, batches, pallet_proxy, Proxy);
|
|
add_benchmark!(params, batches, pallet_scheduler, Scheduler);
|
|
add_benchmark!(params, batches, pallet_session, SessionBench::<Runtime>);
|
|
add_benchmark!(params, batches, pallet_staking, Staking);
|
|
add_benchmark!(params, batches, frame_system, SystemBench::<Runtime>);
|
|
add_benchmark!(params, batches, pallet_timestamp, Timestamp);
|
|
add_benchmark!(params, batches, pallet_tips, Tips);
|
|
add_benchmark!(params, batches, pallet_treasury, Treasury);
|
|
add_benchmark!(params, batches, pallet_utility, Utility);
|
|
add_benchmark!(params, batches, pallet_vesting, Vesting);
|
|
|
|
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
|
|
Ok(batches)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests_fess {
|
|
use super::*;
|
|
use sp_runtime::assert_eq_error_rate;
|
|
|
|
#[test]
|
|
fn signed_deposit_is_sensible() {
|
|
// ensure this number does not change, or that it is checked after each change.
|
|
// a 1 MB solution should need around 0.16 KSM deposit
|
|
let deposit = SignedDepositBase::get() + (SignedDepositByte::get() * 1024 * 1024);
|
|
assert_eq_error_rate!(deposit, UNITS * 16 / 100, UNITS / 100);
|
|
}
|
|
}
|