mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-02 00:07:23 +00:00
444d4e204c
* implement max_values + storages info * some formatting + doc * sudo sanity check * timestamp * assets (not working) * fix assets * impl for proxy * update balances * rename StoragesInfo -> PalletStorageInfo * merge both StorageInfoTrait and PalletStorageInfo I think it is more future proof. In the future some storage could make use of multiple prefix. Like one to store how much value has been inserted, etc... * Update frame/support/procedural/src/storage/parse.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * Update frame/support/procedural/src/storage/storage_struct.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * Fix max_size using hasher information hasher now expose `max_len` which allows to computes their maximum len. For hasher without concatenation, it is the size of the hash part, for hasher with concatenation, it is the size of the hash part + max encoded len of the key. * fix tests * fix ui tests * Move `MaxBoundedLen` into its own crate (#8814) * move MaxEncodedLen into its own crate * remove MaxEncodedLen impl from frame-support * add to assets and balances * try more fixes * fix compile Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * nits * fix compile * line width * fix max-values-macro merge * Add some derive, needed for test and other purpose * use weak bounded vec in some cases * Update lib.rs * move max-encoded-len crate * fix * remove app crypto for now * width * Revert "remove app crypto for now" This reverts commit 73623e9933d50648e0e7fe90b6171a8e45d7f5a2. * unused variable * more unused variables * more fixes * Add #[max_encoded_len_crate(...)] helper attribute The purpose of this attribute is to reduce the surface area of max_encoded_len changes. Crates deriving `MaxEncodedLen` do not need to add it to `Cargo.toml`; they can instead just do ```rust \#[derive(Encode, MaxEncodedLen)] \#[max_encoded_len_crate(frame_support::max_encoded_len)] struct Example; ``` * fix a ui test * use #[max_encoded_len_crate(...)] helper in app_crypto * remove max_encoded_len import where not necessary * update lockfile * fix ui test * ui * newline * fix merge * try fix ui again * Update max-encoded-len/derive/src/lib.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * extract generate_crate_access_2018 * Update lib.rs * compiler isnt smart enough Co-authored-by: thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> Co-authored-by: Peter Goodspeed-Niklaus <peter.r.goodspeedniklaus@gmail.com>
1534 lines
54 KiB
Rust
1534 lines
54 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// 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
|
|
// (at your option) any later version.
|
|
|
|
// 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.
|
|
|
|
#![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 sp_std::prelude::*;
|
|
use frame_support::{
|
|
construct_runtime, parameter_types, RuntimeDebug,
|
|
weights::{
|
|
Weight, IdentityFee,
|
|
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
|
|
DispatchClass,
|
|
},
|
|
traits::{
|
|
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, LockIdentifier,
|
|
U128CurrencyToVote, MaxEncodedLen,
|
|
},
|
|
};
|
|
use frame_system::{
|
|
EnsureRoot, EnsureOneOf,
|
|
limits::{BlockWeights, BlockLength}
|
|
};
|
|
use frame_support::{traits::InstanceFilter, PalletId};
|
|
use codec::{Encode, Decode};
|
|
use sp_core::{
|
|
crypto::KeyTypeId,
|
|
u32_trait::{_1, _2, _3, _4, _5},
|
|
OpaqueMetadata,
|
|
};
|
|
pub use node_primitives::{AccountId, Signature};
|
|
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
|
|
use sp_api::impl_runtime_apis;
|
|
use sp_runtime::{
|
|
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic,
|
|
create_runtime_str, FixedPointNumber,
|
|
};
|
|
use sp_runtime::curve::PiecewiseLinear;
|
|
use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority};
|
|
use sp_runtime::traits::{
|
|
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys,
|
|
NumberFor,
|
|
};
|
|
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 static_assertions::const_assert;
|
|
use pallet_contracts::weights::WeightInfo;
|
|
|
|
#[cfg(any(feature = "std", test))]
|
|
pub use sp_runtime::BuildStorage;
|
|
#[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.
|
|
pub mod impls;
|
|
use impls::Author;
|
|
|
|
/// Constant values used within the runtime.
|
|
pub mod constants;
|
|
use constants::{time::*, currency::*};
|
|
use sp_runtime::generic::Era;
|
|
|
|
// 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.
|
|
#[sp_version::runtime_version]
|
|
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|
spec_name: create_runtime_str!("node"),
|
|
impl_name: create_runtime_str!("substrate-node"),
|
|
authoring_version: 10,
|
|
// 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: 266,
|
|
impl_version: 0,
|
|
apis: RUNTIME_API_VERSIONS,
|
|
transaction_version: 2,
|
|
};
|
|
|
|
/// 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;
|
|
|
|
parameter_types! {
|
|
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 BaseCallFilter = ();
|
|
type BlockWeights = RuntimeBlockWeights;
|
|
type BlockLength = RuntimeBlockLength;
|
|
type DbWeight = RocksDbWeight;
|
|
type Origin = Origin;
|
|
type Call = Call;
|
|
type Index = Index;
|
|
type BlockNumber = BlockNumber;
|
|
type Hash = Hash;
|
|
type Hashing = BlakeTwo256;
|
|
type AccountId = AccountId;
|
|
type Lookup = Indices;
|
|
type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
|
type Event = Event;
|
|
type BlockHashCount = BlockHashCount;
|
|
type Version = Version;
|
|
type PalletInfo = PalletInfo;
|
|
type AccountData = pallet_balances::AccountData<Balance>;
|
|
type OnNewAccount = ();
|
|
type OnKilledAccount = ();
|
|
type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
|
|
type SS58Prefix = SS58Prefix;
|
|
type OnSetCode = ();
|
|
}
|
|
|
|
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, MaxEncodedLen)]
|
|
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>;
|
|
}
|
|
|
|
parameter_types! {
|
|
// NOTE: Currently it is not possible to change the epoch duration after the chain has started.
|
|
// Attempting to do so will brick block production.
|
|
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 AccountIndex = AccountIndex;
|
|
type Currency = Balances;
|
|
type Deposit = IndexDeposit;
|
|
type Event = Event;
|
|
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 MaxLocks = MaxLocks;
|
|
type Balance = Balance;
|
|
type DustRemoval = ();
|
|
type Event = Event;
|
|
type ExistentialDeposit = ExistentialDeposit;
|
|
type AccountStore = frame_system::Pallet<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>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
|
|
}
|
|
|
|
impl pallet_timestamp::Config for Runtime {
|
|
type Moment = Moment;
|
|
type OnTimestampSet = Babe;
|
|
type MinimumPeriod = MinimumPeriod;
|
|
type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
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);
|
|
}
|
|
|
|
impl_opaque_keys! {
|
|
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 Event = Event;
|
|
type ValidatorId = <Self as frame_system::Config>::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 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>;
|
|
}
|
|
|
|
pallet_staking_reward_curve::build! {
|
|
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,
|
|
);
|
|
}
|
|
|
|
parameter_types! {
|
|
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;
|
|
pub OffchainRepeat: BlockNumber = 5;
|
|
}
|
|
|
|
impl pallet_staking::Config for Runtime {
|
|
const MAX_NOMINATIONS: u32 = MAX_NOMINATIONS;
|
|
type Currency = Balances;
|
|
type UnixTime = Timestamp;
|
|
type CurrencyToVote = U128CurrencyToVote;
|
|
type RewardRemainder = Treasury;
|
|
type Event = Event;
|
|
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 EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
|
|
type NextNewSession = Session;
|
|
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
|
|
type ElectionProvider = ElectionProviderMultiPhase;
|
|
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
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::OnChain;
|
|
|
|
pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(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());
|
|
// Solution can occupy 90% of normal block size
|
|
pub MinerMaxLength: u32 = Perbill::from_rational(9u32, 10) *
|
|
*RuntimeBlockLength::get()
|
|
.max
|
|
.get(DispatchClass::Normal);
|
|
}
|
|
|
|
sp_npos_elections::generate_solution_type!(
|
|
#[compact]
|
|
pub struct NposCompactSolution16::<
|
|
VoterIndex = u32,
|
|
TargetIndex = u16,
|
|
Accuracy = sp_runtime::PerU16,
|
|
>(16)
|
|
);
|
|
|
|
pub const MAX_NOMINATIONS: u32 =
|
|
<NposCompactSolution16 as sp_npos_elections::CompactSolution>::LIMIT as u32;
|
|
|
|
impl pallet_election_provider_multi_phase::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type SignedPhase = SignedPhase;
|
|
type UnsignedPhase = UnsignedPhase;
|
|
type SolutionImprovementThreshold = SolutionImprovementThreshold;
|
|
type OffchainRepeat = OffchainRepeat;
|
|
type MinerMaxIterations = MinerMaxIterations;
|
|
type MinerMaxWeight = MinerMaxWeight;
|
|
type MinerMaxLength = MinerMaxLength;
|
|
type MinerTxPriority = MultiPhaseUnsignedPriority;
|
|
type DataProvider = Staking;
|
|
type OnChainAccuracy = Perbill;
|
|
type CompactSolution = NposCompactSolution16;
|
|
type Fallback = Fallback;
|
|
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Runtime>;
|
|
type ForceOrigin = EnsureRootOrHalfCouncil;
|
|
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 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 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 Slash = Treasury;
|
|
type Scheduler = Scheduler;
|
|
type PalletsOrigin = OriginCaller;
|
|
type MaxVotes = MaxVotes;
|
|
type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
|
|
type MaxProposals = MaxProposals;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const CouncilMotionDuration: BlockNumber = 5 * 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 = 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 ElectionsPhragmenPalletId: 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 Event = Event;
|
|
type PalletId = ElectionsPhragmenPalletId;
|
|
type Currency = Balances;
|
|
type ChangeMembers = Council;
|
|
// 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 Event = Event;
|
|
type AddOrigin = EnsureRootOrHalfCouncil;
|
|
type RemoveOrigin = EnsureRootOrHalfCouncil;
|
|
type SwapOrigin = EnsureRootOrHalfCouncil;
|
|
type ResetOrigin = EnsureRootOrHalfCouncil;
|
|
type PrimeOrigin = EnsureRootOrHalfCouncil;
|
|
type MembershipInitialized = TechnicalCommittee;
|
|
type MembershipChanged = TechnicalCommittee;
|
|
type MaxMembers = TechnicalMaxMembers;
|
|
type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
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 TreasuryPalletId: PalletId = PalletId(*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;
|
|
pub const MaxApprovals: u32 = 100;
|
|
}
|
|
|
|
impl pallet_treasury::Config for Runtime {
|
|
type PalletId = TreasuryPalletId;
|
|
type Currency = Balances;
|
|
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 Event = Event;
|
|
type OnSlash = ();
|
|
type ProposalBond = ProposalBond;
|
|
type ProposalBondMinimum = ProposalBondMinimum;
|
|
type SpendPeriod = SpendPeriod;
|
|
type Burn = Burn;
|
|
type BurnDestination = ();
|
|
type SpendFunds = Bounties;
|
|
type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
|
|
type MaxApprovals = MaxApprovals;
|
|
}
|
|
|
|
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 MaximumReasonLength = MaximumReasonLength;
|
|
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>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub TombstoneDeposit: Balance = deposit(
|
|
1,
|
|
<pallet_contracts::Pallet<Runtime>>::contract_info_size(),
|
|
);
|
|
pub DepositPerContract: Balance = TombstoneDeposit::get();
|
|
pub const DepositPerStorageByte: Balance = deposit(0, 1);
|
|
pub const DepositPerStorageItem: Balance = deposit(1, 0);
|
|
pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
|
|
pub const SurchargeReward: Balance = 150 * MILLICENTS;
|
|
pub const SignedClaimHandicap: u32 = 2;
|
|
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 Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
|
|
}
|
|
|
|
impl pallet_contracts::Config for Runtime {
|
|
type Time = Timestamp;
|
|
type Randomness = RandomnessCollectiveFlip;
|
|
type Currency = Balances;
|
|
type Event = Event;
|
|
type RentPayment = ();
|
|
type SignedClaimHandicap = SignedClaimHandicap;
|
|
type TombstoneDeposit = TombstoneDeposit;
|
|
type DepositPerContract = DepositPerContract;
|
|
type DepositPerStorageByte = DepositPerStorageByte;
|
|
type DepositPerStorageItem = DepositPerStorageItem;
|
|
type RentFraction = RentFraction;
|
|
type SurchargeReward = SurchargeReward;
|
|
type CallStack = [pallet_contracts::Frame<Self>; 31];
|
|
type WeightPrice = pallet_transaction_payment::Module<Self>;
|
|
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
|
|
type ChainExtension = ();
|
|
type DeletionQueueDepth = DeletionQueueDepth;
|
|
type DeletionWeightLimit = DeletionWeightLimit;
|
|
type Schedule = Schedule;
|
|
}
|
|
|
|
impl pallet_sudo::Config for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
}
|
|
|
|
parameter_types! {
|
|
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)> {
|
|
let tip = 0;
|
|
// 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::CheckGenesis::<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;
|
|
type OverarchingCall = Call;
|
|
}
|
|
|
|
impl pallet_im_online::Config for Runtime {
|
|
type AuthorityId = ImOnlineId;
|
|
type Event = Event;
|
|
type NextSessionRotation = Babe;
|
|
type ValidatorSet = Historical;
|
|
type ReportUnresponsiveness = Offences;
|
|
type UnsignedPriority = ImOnlineUnsignedPriority;
|
|
type WeightInfo = pallet_im_online::weights::SubstrateWeight<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 {}
|
|
|
|
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 = ();
|
|
}
|
|
|
|
parameter_types! {
|
|
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 Slashed = Treasury;
|
|
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 MaxCandidateIntake: u32 = 10;
|
|
pub const SocietyPalletId: PalletId = PalletId(*b"py/socie");
|
|
}
|
|
|
|
impl pallet_society::Config for Runtime {
|
|
type Event = Event;
|
|
type PalletId = SocietyPalletId;
|
|
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 MaxCandidateIntake = MaxCandidateIntake;
|
|
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;
|
|
type MinVestedTransfer = MinVestedTransfer;
|
|
type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
impl pallet_mmr::Config for Runtime {
|
|
const INDEXING_PREFIX: &'static [u8] = b"mmr";
|
|
type Hashing = <Runtime as frame_system::Config>::Hashing;
|
|
type Hash = <Runtime as frame_system::Config>::Hash;
|
|
type LeafData = frame_system::Pallet<Self>;
|
|
type OnNewRoot = ();
|
|
type WeightInfo = ();
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const LotteryPalletId: PalletId = PalletId(*b"py/lotto");
|
|
pub const MaxCalls: u32 = 10;
|
|
pub const MaxGenerateRandom: u32 = 10;
|
|
}
|
|
|
|
impl pallet_lottery::Config for Runtime {
|
|
type PalletId = LotteryPalletId;
|
|
type Call = Call;
|
|
type Currency = Balances;
|
|
type Randomness = RandomnessCollectiveFlip;
|
|
type Event = Event;
|
|
type ManagerOrigin = EnsureRoot<AccountId>;
|
|
type MaxCalls = MaxCalls;
|
|
type ValidateCall = Lottery;
|
|
type MaxGenerateRandom = MaxGenerateRandom;
|
|
type WeightInfo = pallet_lottery::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const AssetDeposit: Balance = 100 * DOLLARS;
|
|
pub const ApprovalDeposit: Balance = 1 * DOLLARS;
|
|
pub const StringLimit: u32 = 50;
|
|
pub const MetadataDepositBase: Balance = 10 * DOLLARS;
|
|
pub const MetadataDepositPerByte: Balance = 1 * DOLLARS;
|
|
}
|
|
|
|
impl pallet_assets::Config for Runtime {
|
|
type Event = Event;
|
|
type Balance = u64;
|
|
type AssetId = u32;
|
|
type Currency = Balances;
|
|
type ForceOrigin = EnsureRoot<AccountId>;
|
|
type AssetDeposit = AssetDeposit;
|
|
type MetadataDepositBase = MetadataDepositBase;
|
|
type MetadataDepositPerByte = MetadataDepositPerByte;
|
|
type ApprovalDeposit = ApprovalDeposit;
|
|
type StringLimit = StringLimit;
|
|
type Freezer = ();
|
|
type Extra = ();
|
|
type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub IgnoredIssuance: Balance = Treasury::pot();
|
|
pub const QueueCount: u32 = 300;
|
|
pub const MaxQueueLen: u32 = 1000;
|
|
pub const FifoQueueLen: u32 = 500;
|
|
pub const Period: BlockNumber = 30 * DAYS;
|
|
pub const MinFreeze: Balance = 100 * DOLLARS;
|
|
pub const IntakePeriod: BlockNumber = 10;
|
|
pub const MaxIntakeBids: u32 = 10;
|
|
}
|
|
|
|
impl pallet_gilt::Config for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type CurrencyBalance = Balance;
|
|
type AdminOrigin = frame_system::EnsureRoot<AccountId>;
|
|
type Deficit = ();
|
|
type Surplus = ();
|
|
type IgnoredIssuance = IgnoredIssuance;
|
|
type QueueCount = QueueCount;
|
|
type MaxQueueLen = MaxQueueLen;
|
|
type FifoQueueLen = FifoQueueLen;
|
|
type Period = Period;
|
|
type MinFreeze = MinFreeze;
|
|
type IntakePeriod = IntakePeriod;
|
|
type MaxIntakeBids = MaxIntakeBids;
|
|
type WeightInfo = pallet_gilt::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
construct_runtime!(
|
|
pub enum Runtime where
|
|
Block = Block,
|
|
NodeBlock = node_primitives::Block,
|
|
UncheckedExtrinsic = UncheckedExtrinsic
|
|
{
|
|
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
|
Utility: pallet_utility::{Pallet, Call, Event},
|
|
Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned},
|
|
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
|
|
Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent},
|
|
Indices: pallet_indices::{Pallet, Call, Storage, Config<T>, Event<T>},
|
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
|
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
|
|
ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event<T>, ValidateUnsigned},
|
|
Staking: pallet_staking::{Pallet, Call, Config<T>, Storage, Event<T>},
|
|
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
|
|
Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event<T>},
|
|
Council: pallet_collective::<Instance1>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>},
|
|
TechnicalCommittee: pallet_collective::<Instance2>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>},
|
|
Elections: pallet_elections_phragmen::{Pallet, Call, Storage, Event<T>, Config<T>},
|
|
TechnicalMembership: pallet_membership::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>},
|
|
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned},
|
|
Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>},
|
|
Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>},
|
|
Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>},
|
|
ImOnline: pallet_im_online::{Pallet, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
|
|
AuthorityDiscovery: pallet_authority_discovery::{Pallet, Call, Config},
|
|
Offences: pallet_offences::{Pallet, Call, Storage, Event},
|
|
Historical: pallet_session_historical::{Pallet},
|
|
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Call, Storage},
|
|
Identity: pallet_identity::{Pallet, Call, Storage, Event<T>},
|
|
Society: pallet_society::{Pallet, Call, Storage, Event<T>, Config<T>},
|
|
Recovery: pallet_recovery::{Pallet, Call, Storage, Event<T>},
|
|
Vesting: pallet_vesting::{Pallet, Call, Storage, Event<T>, Config<T>},
|
|
Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>},
|
|
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>},
|
|
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>},
|
|
Bounties: pallet_bounties::{Pallet, Call, Storage, Event<T>},
|
|
Tips: pallet_tips::{Pallet, Call, Storage, Event<T>},
|
|
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>},
|
|
Mmr: pallet_mmr::{Pallet, Storage},
|
|
Lottery: pallet_lottery::{Pallet, Call, Storage, Event<T>},
|
|
Gilt: pallet_gilt::{Pallet, Call, Storage, Event<T>, Config},
|
|
}
|
|
);
|
|
|
|
/// The address format for describing accounts.
|
|
pub type Address = sp_runtime::MultiAddress<AccountId, AccountIndex>;
|
|
/// 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.
|
|
///
|
|
/// When you change this, you **MUST** modify [`sign`] in `bin/node/testing/src/keyring.rs`!
|
|
///
|
|
/// [`sign`]: <../../testing/src/keyring.rs.html>
|
|
pub type SignedExtra = (
|
|
frame_system::CheckSpecVersion<Runtime>,
|
|
frame_system::CheckTxVersion<Runtime>,
|
|
frame_system::CheckGenesis<Runtime>,
|
|
frame_system::CheckEra<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>;
|
|
/// The payload being signed in transactions.
|
|
pub type SignedPayload = generic::SignedPayload<Call, SignedExtra>;
|
|
/// Extrinsic type that has already been checked.
|
|
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
|
|
/// Executive: handles dispatch to the various modules.
|
|
pub type Executive = frame_executive::Executive<
|
|
Runtime,
|
|
Block,
|
|
frame_system::ChainContext<Runtime>,
|
|
Runtime,
|
|
AllPallets,
|
|
(),
|
|
>;
|
|
|
|
/// MMR helper types.
|
|
mod mmr {
|
|
use super::Runtime;
|
|
pub use pallet_mmr::primitives::*;
|
|
|
|
pub type Leaf = <
|
|
<Runtime as pallet_mmr::Config>::LeafData
|
|
as
|
|
LeafDataProvider
|
|
>::LeafData;
|
|
pub type Hash = <Runtime as pallet_mmr::Config>::Hash;
|
|
pub type Hashing = <Runtime as pallet_mmr::Config>::Hashing;
|
|
}
|
|
|
|
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 {
|
|
Runtime::metadata().into()
|
|
}
|
|
}
|
|
|
|
impl sp_block_builder::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: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
|
|
data.create_extrinsics()
|
|
}
|
|
|
|
fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
|
|
data.check_extrinsics(&block)
|
|
}
|
|
}
|
|
|
|
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
|
|
fn validate_transaction(
|
|
source: TransactionSource,
|
|
tx: <Block as BlockT>::Extrinsic,
|
|
) -> TransactionValidity {
|
|
Executive::validate_transaction(source, tx)
|
|
}
|
|
}
|
|
|
|
impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
|
|
fn offchain_worker(header: &<Block as BlockT>::Header) {
|
|
Executive::offchain_worker(header)
|
|
}
|
|
}
|
|
|
|
impl fg_primitives::GrandpaApi<Block> for Runtime {
|
|
fn grandpa_authorities() -> GrandpaAuthorityList {
|
|
Grandpa::grandpa_authorities()
|
|
}
|
|
|
|
fn submit_report_equivocation_unsigned_extrinsic(
|
|
equivocation_proof: fg_primitives::EquivocationProof<
|
|
<Block as BlockT>::Hash,
|
|
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: GrandpaId,
|
|
) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
|
|
use codec::Encode;
|
|
|
|
Historical::prove((fg_primitives::KEY_TYPE, authority_id))
|
|
.map(|p| p.encode())
|
|
.map(fg_primitives::OpaqueKeyOwnershipProof::new)
|
|
}
|
|
}
|
|
|
|
impl sp_consensus_babe::BabeApi<Block> for Runtime {
|
|
fn configuration() -> sp_consensus_babe::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>
|
|
sp_consensus_babe::BabeGenesisConfiguration {
|
|
slot_duration: Babe::slot_duration(),
|
|
epoch_length: EpochDuration::get(),
|
|
c: BABE_GENESIS_EPOCH_CONFIG.c,
|
|
genesis_authorities: Babe::authorities(),
|
|
randomness: Babe::randomness(),
|
|
allowed_slots: BABE_GENESIS_EPOCH_CONFIG.allowed_slots,
|
|
}
|
|
}
|
|
|
|
fn current_epoch_start() -> sp_consensus_babe::Slot {
|
|
Babe::current_epoch_start()
|
|
}
|
|
|
|
fn current_epoch() -> sp_consensus_babe::Epoch {
|
|
Babe::current_epoch()
|
|
}
|
|
|
|
fn next_epoch() -> sp_consensus_babe::Epoch {
|
|
Babe::next_epoch()
|
|
}
|
|
|
|
fn generate_key_ownership_proof(
|
|
_slot: sp_consensus_babe::Slot,
|
|
authority_id: sp_consensus_babe::AuthorityId,
|
|
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
|
|
use codec::Encode;
|
|
|
|
Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id))
|
|
.map(|p| p.encode())
|
|
.map(sp_consensus_babe::OpaqueKeyOwnershipProof::new)
|
|
}
|
|
|
|
fn submit_report_equivocation_unsigned_extrinsic(
|
|
equivocation_proof: sp_consensus_babe::EquivocationProof<<Block as BlockT>::Header>,
|
|
key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
|
|
) -> Option<()> {
|
|
let key_owner_proof = key_owner_proof.decode()?;
|
|
|
|
Babe::submit_unsigned_equivocation_report(
|
|
equivocation_proof,
|
|
key_owner_proof,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
|
|
fn authorities() -> Vec<AuthorityDiscoveryId> {
|
|
AuthorityDiscovery::authorities()
|
|
}
|
|
}
|
|
|
|
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
|
|
fn account_nonce(account: AccountId) -> Index {
|
|
System::account_nonce(account)
|
|
}
|
|
}
|
|
|
|
impl pallet_contracts_rpc_runtime_api::ContractsApi<
|
|
Block, AccountId, Balance, BlockNumber, Hash,
|
|
>
|
|
for Runtime
|
|
{
|
|
fn call(
|
|
origin: AccountId,
|
|
dest: AccountId,
|
|
value: Balance,
|
|
gas_limit: u64,
|
|
input_data: Vec<u8>,
|
|
) -> pallet_contracts_primitives::ContractExecResult {
|
|
Contracts::bare_call(origin, dest, value, gas_limit, input_data, true)
|
|
}
|
|
|
|
fn instantiate(
|
|
origin: AccountId,
|
|
endowment: Balance,
|
|
gas_limit: u64,
|
|
code: pallet_contracts_primitives::Code<Hash>,
|
|
data: Vec<u8>,
|
|
salt: Vec<u8>,
|
|
) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>
|
|
{
|
|
Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, true)
|
|
}
|
|
|
|
fn get_storage(
|
|
address: AccountId,
|
|
key: [u8; 32],
|
|
) -> pallet_contracts_primitives::GetStorageResult {
|
|
Contracts::get_storage(address, key)
|
|
}
|
|
|
|
fn rent_projection(
|
|
address: AccountId,
|
|
) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
|
|
Contracts::rent_projection(address)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
impl pallet_mmr::primitives::MmrApi<
|
|
Block,
|
|
mmr::Hash,
|
|
> for Runtime {
|
|
fn generate_proof(leaf_index: u64)
|
|
-> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof<mmr::Hash>), mmr::Error>
|
|
{
|
|
Mmr::generate_proof(leaf_index)
|
|
.map(|(leaf, proof)| (mmr::EncodableOpaqueLeaf::from_leaf(&leaf), proof))
|
|
}
|
|
|
|
fn verify_proof(leaf: mmr::EncodableOpaqueLeaf, proof: mmr::Proof<mmr::Hash>)
|
|
-> Result<(), mmr::Error>
|
|
{
|
|
let leaf: mmr::Leaf = leaf
|
|
.into_opaque_leaf()
|
|
.try_decode()
|
|
.ok_or(mmr::Error::Verify)?;
|
|
Mmr::verify_leaf(leaf, proof)
|
|
}
|
|
|
|
fn verify_proof_stateless(
|
|
root: mmr::Hash,
|
|
leaf: mmr::EncodableOpaqueLeaf,
|
|
proof: mmr::Proof<mmr::Hash>
|
|
) -> Result<(), mmr::Error> {
|
|
let node = mmr::DataOrHash::Data(leaf.into_opaque_leaf());
|
|
pallet_mmr::verify_leaf_proof::<mmr::Hashing, _>(root, node, proof)
|
|
}
|
|
}
|
|
|
|
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>, KeyTypeId)>> {
|
|
SessionKeys::decode_into_raw_public_keys(&encoded)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "try-runtime")]
|
|
impl frame_try_runtime::TryRuntime<Block> for Runtime {
|
|
fn on_runtime_upgrade() -> Result<(Weight, Weight), sp_runtime::RuntimeString> {
|
|
let weight = Executive::try_runtime_upgrade()?;
|
|
Ok((weight, RuntimeBlockWeights::get().max_block))
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "runtime-benchmarks")]
|
|
impl frame_benchmarking::Benchmark<Block> for Runtime {
|
|
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 the Session Pallet caused cyclic dependency
|
|
// issues. To get around that, we separated the Session benchmarks into its own crate,
|
|
// which is why we need these two lines below.
|
|
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);
|
|
|
|
add_benchmark!(params, batches, pallet_assets, Assets);
|
|
add_benchmark!(params, batches, pallet_babe, Babe);
|
|
add_benchmark!(params, batches, pallet_balances, Balances);
|
|
add_benchmark!(params, batches, pallet_bounties, Bounties);
|
|
add_benchmark!(params, batches, pallet_collective, Council);
|
|
add_benchmark!(params, batches, pallet_contracts, Contracts);
|
|
add_benchmark!(params, batches, pallet_democracy, Democracy);
|
|
add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase);
|
|
add_benchmark!(params, batches, pallet_elections_phragmen, Elections);
|
|
add_benchmark!(params, batches, pallet_gilt, Gilt);
|
|
add_benchmark!(params, batches, pallet_grandpa, Grandpa);
|
|
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_lottery, Lottery);
|
|
add_benchmark!(params, batches, pallet_membership, TechnicalMembership);
|
|
add_benchmark!(params, batches, pallet_mmr, Mmr);
|
|
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 {
|
|
use super::*;
|
|
use frame_system::offchain::CreateSignedTransaction;
|
|
|
|
#[test]
|
|
fn validate_transaction_submitter_bounds() {
|
|
fn is_submit_signed_transaction<T>() where
|
|
T: CreateSignedTransaction<Call>,
|
|
{}
|
|
|
|
is_submit_signed_transaction::<Runtime>();
|
|
}
|
|
}
|