Newer
Older
// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program 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
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
//! The Substrate runtime. This can be compiled with `#[no_std]`, ready for Wasm.
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]
use sp_std::prelude::*;
construct_runtime, parameter_types, RuntimeDebug,
weights::{
Weight, IdentityFee,
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass,
},
traits::{
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier,
U128CurrencyToVote,
},
use frame_system::{
EnsureRoot, EnsureOneOf,
limits::{BlockWeights, BlockLength}
};
use frame_support::traits::InstanceFilter;
u32_trait::{_1, _2, _3, _4, _5},
pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic,
create_runtime_str, ModuleId, FixedPointNumber,
use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority};
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys,
NumberFor,
Bastian Köcher
committed
};
use sp_version::RuntimeVersion;
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use pallet_grandpa::fg_primitives;
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, CurrencyAdapter};
use pallet_session::{historical as pallet_session_historical};
use sp_inherents::{InherentData, CheckInherentsResult};
use pallet_contracts::weights::WeightInfo;
#[cfg(any(feature = "std", test))]
pub use pallet_balances::Call as BalancesCall;
#[cfg(any(feature = "std", test))]
pub use frame_system::Call as SystemCall;
#[cfg(any(feature = "std", test))]
pub use pallet_staking::StakerStatus;
/// Implementations of some helper traits passed into runtime modules as associated types.
/// Constant values used within the runtime.
pub mod constants;
use constants::{time::*, currency::*};
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics.
#[cfg(feature = "std")]
pub fn wasm_binary_unwrap() -> &'static [u8] {
WASM_BINARY.expect("Development wasm binary is not available. This means the client is \
built with `SKIP_WASM_BUILD` flag and it is only usable for \
production chains. Please rebuild with the flag disabled.")
}
/// Runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node"),
impl_name: create_runtime_str!("substrate-node"),
// Per convention: if the runtime behavior changes, increment spec_version
// and set impl_version to 0. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 265,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
/// The BABE epoch configuration at genesis.
pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
sp_consensus_babe::BabeEpochConfiguration {
c: PRIMARY_PROBABILITY,
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots
};
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
}
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance>) {
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, 80% to treasury, 20% to author (though this can be anything)
tips.ration_merge_into(80, 20, &mut split);
}
Treasury::on_unbalanced(split.0);
Author::on_unbalanced(split.1);
}
}
}
/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers.
/// This is used to limit the maximal weight of a single extrinsic.
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
/// by Operational extrinsics.
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
/// We allow for 2 seconds of compute with a 6 second average block time.
const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND;
pub const BlockHashCount: BlockNumber = 2400;
pub const Version: RuntimeVersion = VERSION;
pub RuntimeBlockLength: BlockLength =
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
.base_block(BlockExecutionWeight::get())
.for_class(DispatchClass::all(), |weights| {
weights.base_extrinsic = 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 some 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();
pub const SS58Prefix: u8 = 42;
}
const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());
impl frame_system::Config for Runtime {
type BlockWeights = RuntimeBlockWeights;
type BlockLength = RuntimeBlockLength;
type DbWeight = RocksDbWeight;
type Index = Index;
type BlockNumber = BlockNumber;
type Hash = Hash;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Header = generic::Header<BlockNumber, BlakeTwo256>;
type BlockHashCount = BlockHashCount;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
type SS58Prefix = SS58Prefix;
impl pallet_utility::Config for Runtime {
type Event = Event;
type Call = Call;
type WeightInfo = pallet_utility::weights::SubstrateWeight<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 = pallet_multisig::weights::SubstrateWeight<Runtime>;
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)]
pub enum ProxyType {
Any,
NonTransfer,
Governance,
Staking,
}
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::Balances(..) |
Call::Vesting(pallet_vesting::Call::vested_transfer(..)) |
Call::Indices(pallet_indices::Call::transfer(..))
ProxyType::Governance => matches!(
c,
Call::Democracy(..) |
Call::Council(..) |
Call::Society(..) |
Call::TechnicalCommittee(..) |
Call::Elections(..) |
Call::Treasury(..)
),
ProxyType::Staking => matches!(c, Call::Staking(..)),
}
}
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 = pallet_proxy::weights::SubstrateWeight<Runtime>;
type MaxPending = MaxPending;
type CallHasher = BlakeTwo256;
type AnnouncementDepositBase = AnnouncementDepositBase;
type AnnouncementDepositFactor = AnnouncementDepositFactor;
parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
RuntimeBlockWeights::get().max_block;
pub const MaxScheduledPerBlock: u32 = 50;
}
impl pallet_scheduler::Config for Runtime {
type Event = Event;
type Origin = Origin;
type PalletsOrigin = OriginCaller;
type Call = Call;
type MaximumWeight = MaximumSchedulerWeight;
type ScheduleOrigin = EnsureRoot<AccountId>;
type MaxScheduledPerBlock = MaxScheduledPerBlock;
type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
}
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS;
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;
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
pallet_babe::AuthorityId,
)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
pallet_babe::AuthorityId,
)>>::IdentificationTuple;
type HandleEquivocation =
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
type WeightInfo = ();
parameter_types! {
pub const IndexDeposit: Balance = 1 * DOLLARS;
}
impl pallet_indices::Config for Runtime {
type Currency = Balances;
type Deposit = IndexDeposit;
type WeightInfo = pallet_indices::weights::SubstrateWeight<Runtime>;
parameter_types! {
pub const ExistentialDeposit: Balance = 1 * DOLLARS;
// For weight estimation, we assume that the most locks on an individual account will be 50.
// This number may need to be adjusted in the future if this assumption no longer holds true.
pub const MaxLocks: u32 = 50;
impl pallet_balances::Config for Runtime {
type Balance = Balance;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = frame_system::Module<Runtime>;
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000);
pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128);
impl pallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
type TransactionByteFee = TransactionByteFee;
type WeightToFee = IdentityFee<Balance>;
type FeeMultiplierUpdate =
TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
impl pallet_timestamp::Config for Runtime {
type MinimumPeriod = MinimumPeriod;
type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
pub const UncleGenerations: BlockNumber = 5;
impl pallet_authorship::Config for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
type UncleGenerations = UncleGenerations;
type FilterUncle = ();
type EventHandler = (Staking, ImOnline);
pub struct SessionKeys {
pub grandpa: Grandpa,
pub babe: Babe,
pub im_online: ImOnline,
pub authority_discovery: AuthorityDiscovery,
parameter_types! {
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}
impl pallet_session::Config for Runtime {
type ValidatorId = <Self as frame_system::Config>::AccountId;
type ValidatorIdOf = pallet_staking::StashOf<Self>;
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
impl pallet_session::historical::Config for Runtime {
type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
min_inflation: 0_025_000,
max_inflation: 0_100_000,
ideal_stake: 0_500_000,
falloff: 0_050_000,
max_piece_count: 40,
test_precision: 0_005_000,
);
}
pub const SessionsPerEra: sp_staking::SessionIndex = 6;
pub const BondingDuration: pallet_staking::EraIndex = 24 * 28;
pub const SlashDeferDuration: pallet_staking::EraIndex = 24 * 7; // 1/4 the bonding duration.
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
pub const MaxNominatorRewardedPerValidator: u32 = 256;
Kian Paimani
committed
pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
pub const MaxIterations: u32 = 10;
// 0.05%. The higher the value, the more strict solution acceptance becomes.
pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
pub OffchainSolutionWeightLimit: Weight = RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
.saturating_sub(BlockExecutionWeight::get());
impl pallet_staking::Config for Runtime {
type UnixTime = Timestamp;
type CurrencyToVote = U128CurrencyToVote;
type RewardRemainder = Treasury;
type Slash = Treasury; // send the slashed funds to the treasury.
type Reward = (); // rewards are minted from the void
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type SlashDeferDuration = SlashDeferDuration;
/// A super-majority of the council can cancel the slash.
type SlashCancelOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
>;
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionLookahead = ElectionLookahead;
type Call = Call;
Kian Paimani
committed
type MinSolutionScoreBump = MinSolutionScoreBump;
type UnsignedPriority = StakingUnsignedPriority;
// The unsigned solution weight targeted by the OCW. We set it to the maximum possible value of
// a single extrinsic.
type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
type ElectionProvider = ElectionProviderMultiPhase;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
parameter_types! {
// phase durations. 1/4 of the last session for each.
pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
// fallback: no need to do on-chain phragmen initially.
pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
pallet_election_provider_multi_phase::FallbackStrategy::Nothing;
pub SolutionImprovementThreshold: Perbill = Perbill::from_rational_approximation(1u32, 10_000);
// miner configs
pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
pub const MinerMaxIterations: u32 = 10;
pub MinerMaxWeight: Weight = RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
.saturating_sub(BlockExecutionWeight::get());
}
impl pallet_election_provider_multi_phase::Config for Runtime {
type Event = Event;
type Currency = Balances;
type SignedPhase = SignedPhase;
type UnsignedPhase = UnsignedPhase;
type SolutionImprovementThreshold = MinSolutionScoreBump;
type MinerMaxIterations = MinerMaxIterations;
type MinerMaxWeight = MinerMaxWeight;
type MinerTxPriority = MultiPhaseUnsignedPriority;
type DataProvider = Staking;
type OnChainAccuracy = Perbill;
type CompactSolution = pallet_staking::CompactAssignments;
type Fallback = Fallback;
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Runtime>;
type BenchmarkingConfig = ();
}
parameter_types! {
pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
pub const FastTrackVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
pub const InstantAllowed: bool = true;
pub const MinimumDeposit: Balance = 100 * DOLLARS;
pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
// One cent: $10,000 / MB
pub const PreimageByteDeposit: Balance = 1 * CENTS;
pub const MaxProposals: u32 = 100;
impl pallet_democracy::Config for Runtime {
type Currency = Balances;
type EnactmentPeriod = 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 super-majority can have the next scheduled referendum be a straight majority-carries vote.
type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, 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 = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>;
// 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>,
>;
type BlacklistOrigin = EnsureRoot<AccountId>;
// Any single technical committee member may veto a coming council proposal, however they can
// only do it once and it lasts only for the cool-off period.
type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
type CooloffPeriod = CooloffPeriod;
type PreimageByteDeposit = PreimageByteDeposit;
type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
type Scheduler = Scheduler;
type PalletsOrigin = OriginCaller;
type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
type MaxProposals = MaxProposals;
parameter_types! {
pub const CouncilMotionDuration: BlockNumber = 5 * DAYS;
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 MaxMembers = CouncilMaxMembers;
type DefaultVote = pallet_collective::PrimeDefaultVote;
type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
parameter_types! {
pub const CandidacyBond: Balance = 10 * DOLLARS;
// 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);
pub const TermDuration: BlockNumber = 7 * DAYS;
pub const DesiredMembers: u32 = 13;
pub const DesiredRunnersUp: u32 = 7;
pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
// Make sure that there are no more than `MaxMembers` members elected via elections-phragmen.
const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
impl pallet_elections_phragmen::Config for Runtime {
type ModuleId = ElectionsPhragmenModuleId;
// NOTE: this implies that council's genesis members cannot be set directly and must come from
// this module.
type InitializeMembers = Council;
type CurrencyToVote = U128CurrencyToVote;
type CandidacyBond = CandidacyBond;
type VotingBondBase = VotingBondBase;
type VotingBondFactor = VotingBondFactor;
type LoserCandidate = ();
type KickedMember = ();
type DesiredMembers = DesiredMembers;
type DesiredRunnersUp = DesiredRunnersUp;
type TermDuration = TermDuration;
type WeightInfo = pallet_elections_phragmen::weights::SubstrateWeight<Runtime>;
parameter_types! {
pub const TechnicalMotionDuration: BlockNumber = 5 * 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 = pallet_collective::weights::SubstrateWeight<Runtime>;
type EnsureRootOrHalfCouncil = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
>;
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
type AddOrigin = EnsureRootOrHalfCouncil;
type RemoveOrigin = EnsureRootOrHalfCouncil;
type SwapOrigin = EnsureRootOrHalfCouncil;
type ResetOrigin = EnsureRootOrHalfCouncil;
type PrimeOrigin = EnsureRootOrHalfCouncil;
type MembershipInitialized = TechnicalCommittee;
type MembershipChanged = TechnicalCommittee;
}
parameter_types! {
pub const ProposalBond: Permill = Permill::from_percent(5);
pub const ProposalBondMinimum: Balance = 1 * DOLLARS;
pub const SpendPeriod: BlockNumber = 1 * DAYS;
pub const Burn: Permill = Permill::from_percent(50);
pub const TipCountdown: BlockNumber = 1 * DAYS;
pub const TipFindersFee: Percent = Percent::from_percent(20);
pub const TipReportDepositBase: Balance = 1 * DOLLARS;
pub const DataDepositPerByte: Balance = 1 * CENTS;
pub const BountyDepositBase: Balance = 1 * DOLLARS;
pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
pub const MaximumReasonLength: u32 = 16384;
pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
pub const BountyValueMinimum: Balance = 5 * DOLLARS;
impl pallet_treasury::Config for Runtime {
type ApproveOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
>;
type RejectOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
type ProposalBond = ProposalBond;
type ProposalBondMinimum = ProposalBondMinimum;
type SpendPeriod = SpendPeriod;
type Burn = Burn;
type BurnDestination = ();
type SpendFunds = Bounties;
type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
}
impl pallet_bounties::Config for Runtime {
type Event = Event;
type BountyDepositBase = BountyDepositBase;
type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
type BountyUpdatePeriod = BountyUpdatePeriod;
type BountyCuratorDeposit = BountyCuratorDeposit;
type BountyValueMinimum = BountyValueMinimum;
type DataDepositPerByte = DataDepositPerByte;
type WeightInfo = pallet_bounties::weights::SubstrateWeight<Runtime>;
}
impl pallet_tips::Config for Runtime {
type Event = Event;
type DataDepositPerByte = DataDepositPerByte;
type MaximumReasonLength = MaximumReasonLength;
type Tippers = Elections;
type TipCountdown = TipCountdown;
type TipFindersFee = TipFindersFee;
type TipReportDepositBase = TipReportDepositBase;
type WeightInfo = pallet_tips::weights::SubstrateWeight<Runtime>;
pub const TombstoneDeposit: Balance = deposit(
1,
sp_std::mem::size_of::<pallet_contracts::ContractInfo<Runtime>>() as u32
);
pub const DepositPerContract: Balance = TombstoneDeposit::get();
pub const DepositPerStorageByte: Balance = deposit(0, 1);
pub const DepositPerStorageItem: Balance = deposit(1, 0);
pub RentFraction: Perbill = Perbill::from_rational_approximation(1u32, 30 * DAYS);
pub const SurchargeReward: Balance = 150 * MILLICENTS;
pub const SignedClaimHandicap: u32 = 2;
pub const MaxDepth: u32 = 32;
pub const MaxValueSize: u32 = 16 * 1024;
// The lazy deletion runs inside on_initialize.
pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
RuntimeBlockWeights::get().max_block;
// The weight needed for decoding the queue should be less or equal than a fifth
// of the overall weight dedicated to the lazy deletion.
pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
)) / 5) as u32;
pub MaxCodeSize: u32 = 128 * 1024;
impl pallet_contracts::Config for Runtime {
type Randomness = RandomnessCollectiveFlip;
type RentPayment = ();
type SignedClaimHandicap = SignedClaimHandicap;
type TombstoneDeposit = TombstoneDeposit;
type DepositPerContract = DepositPerContract;
type DepositPerStorageByte = DepositPerStorageByte;
type DepositPerStorageItem = DepositPerStorageItem;
type RentFraction = RentFraction;
type SurchargeReward = SurchargeReward;
type MaxDepth = MaxDepth;
type MaxValueSize = MaxValueSize;
type WeightPrice = pallet_transaction_payment::Module<Self>;
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
type ChainExtension = ();
type DeletionQueueDepth = DeletionQueueDepth;
type DeletionWeightLimit = DeletionWeightLimit;
type MaxCodeSize = MaxCodeSize;
impl pallet_sudo::Config for Runtime {
parameter_types! {
pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _;
pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
/// We prioritize im-online heartbeats over election solution submission.
pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
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 traits::Verify>::Signer,
account: AccountId,
nonce: Index,
) -> Option<(Call, <UncheckedExtrinsic as traits::Extrinsic>::SignaturePayload)> {
// 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 era = Era::mortal(period, current_block);
let extra = (
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckEra::<Runtime>::from(era),
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 address = Indices::unlookup(account);
let (call, extra, _) = raw_payload.deconstruct();
Some((call, (address, signature.into(), extra)))
}
}
impl frame_system::offchain::SigningTypes for Runtime {
type Public = <Signature as traits::Verify>::Signer;
type Signature = Signature;
}
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
Call: From<C>,
{
type Extrinsic = UncheckedExtrinsic;
impl pallet_im_online::Config for Runtime {
type ValidatorSet = Historical;
type SessionDuration = SessionDuration;
type UnsignedPriority = ImOnlineUnsignedPriority;
type WeightInfo = pallet_im_online::weights::SubstrateWeight<Runtime>;
pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) *
RuntimeBlockWeights::get().max_block;
impl pallet_offences::Config for Runtime {
type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
type OnOffenceHandler = Staking;
type WeightSoftLimit = OffencesWeightSoftLimit;
impl pallet_authority_discovery::Config for Runtime {}
impl pallet_grandpa::Config for Runtime {
type Event = Event;
type Call = Call;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof =
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
GrandpaId,
)>>::IdentificationTuple;
type HandleEquivocation =
pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
type WeightInfo = ();
pub const BasicDeposit: Balance = 10 * DOLLARS; // 258 bytes on-chain
pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain
pub const SubAccountDeposit: Balance = 2 * DOLLARS; // 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 ForceOrigin = EnsureRootOrHalfCouncil;
type RegistrarOrigin = EnsureRootOrHalfCouncil;
type WeightInfo = pallet_identity::weights::SubstrateWeight<Runtime>;
parameter_types! {
pub const ConfigDepositBase: Balance = 5 * DOLLARS;
pub const FriendDepositFactor: Balance = 50 * CENTS;
pub const MaxFriends: u16 = 9;
pub const RecoveryDeposit: Balance = 5 * DOLLARS;
}
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 = 10 * DOLLARS;
pub const WrongSideDeduction: Balance = 2 * DOLLARS;
pub const MaxStrikes: u32 = 10;
pub const RotationPeriod: BlockNumber = 80 * HOURS;
pub const PeriodSpend: Balance = 500 * DOLLARS;
pub const MaxLockDuration: BlockNumber = 36 * 30 * DAYS;
pub const ChallengePeriod: BlockNumber = 7 * DAYS;
pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie");
}
impl pallet_society::Config for Runtime {
type Event = Event;
type Currency = Balances;
type Randomness = RandomnessCollectiveFlip;
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;
}
parameter_types! {
pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}
impl pallet_vesting::Config for Runtime {
type Event = Event;
type Currency = Balances;
type BlockNumberToBalance = ConvertInto;