mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 14:37:57 +00:00
c3ca78fae3
* pallet-contracts: Fix seal_restore_to to output proper module errors Those errors where part of the decl_error for some time but where never actually returned. This allows proper debugging of failed restorations. Previously, any error did return the misleading `ContractTrapped`. * Bind UncheckedFrom<T::Hash> + AsRef<[u8]> everywhere This allows us to make assumptions about the AccoutId that are necessary for testing and in order to benchmark the module properly. This also groups free standing functions into inherent functions in order to minimize the places where the new bounds need to be specified. * Rework contract address determination * Do not allow override by runtime author * Instantiate gained a new parameter "salt" This change is done now in expecation of the upcoming code rent which needs to change the instantiation dispatchable and host function anyways. The situation in where we have only something that is like CREATE2 makes it impossible for UIs to help the user to create an arbitrary amount of instantiations from the same code. With this change we have the same functionality as ethereum with a CREATE and CREATE2 instantation semantic. * Remove TrieIdGenerator The new trait bounds allows us to remove this workaround from the configuration trait. * Remove default parameters for config trait It should be solely the responsiblity to determine proper values for these parameter. As a matter of fact most runtime weren't using these values anyways. * Fix tests for new account id type Because of the new bounds on the trait tests can't get away by using u64 as accound id. Replacing the 8 byte value by a 32 byte value creates out quite a bit of code churn. * Fix benchmarks The benchmarks need adaption to the new instantiate semantics. * Fix compile errors caused by adding new trait bounds * Fix compile errors caused by renaming storage and rent functions * Adapt host functions and dispatchables to the new salt * Add tests for instantiate host functions (was not possible before) * Add benchmark results * Adapt to the new WeightInfo The new benchmarks add a new parameter for salt "s" to the instantiate weights that needs to be applied. * Fix deploying_wasm_contract_should_work integration test This test is adapted to use the new instantiate signature. * Break overlong line * Break more long lines Co-authored-by: Parity Benchmarking Bot <admin@parity.io>
1240 lines
44 KiB
Rust
1240 lines
44 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) 2018-2020 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, debug, RuntimeDebug,
|
|
weights::{
|
|
Weight, IdentityFee,
|
|
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
|
|
},
|
|
traits::{
|
|
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier,
|
|
U128CurrencyToVote,
|
|
},
|
|
};
|
|
use frame_system::{EnsureRoot, EnsureOneOf};
|
|
use frame_support::traits::InstanceFilter;
|
|
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, ModuleId, 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, Saturating,
|
|
};
|
|
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_rpc_runtime_api::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;
|
|
|
|
#[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.
|
|
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: 260,
|
|
impl_version: 0,
|
|
apis: RUNTIME_API_VERSIONS,
|
|
transaction_version: 2,
|
|
};
|
|
|
|
/// 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_percent(10);
|
|
parameter_types! {
|
|
pub const BlockHashCount: BlockNumber = 2400;
|
|
/// We allow for 2 seconds of compute with a 6 second average block time.
|
|
pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND;
|
|
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
|
|
/// Assume 10% of weight for average on_initialize calls.
|
|
pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get().saturating_sub(AVERAGE_ON_INITIALIZE_WEIGHT)
|
|
* MaximumBlockWeight::get();
|
|
pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
|
|
pub const Version: RuntimeVersion = VERSION;
|
|
}
|
|
|
|
const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct());
|
|
|
|
impl frame_system::Trait for Runtime {
|
|
type BaseCallFilter = ();
|
|
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 MaximumBlockWeight = MaximumBlockWeight;
|
|
type DbWeight = RocksDbWeight;
|
|
type BlockExecutionWeight = BlockExecutionWeight;
|
|
type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
|
|
type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
|
|
type MaximumBlockLength = MaximumBlockLength;
|
|
type AvailableBlockRatio = AvailableBlockRatio;
|
|
type Version = Version;
|
|
type PalletInfo = PalletInfo;
|
|
type AccountData = pallet_balances::AccountData<Balance>;
|
|
type OnNewAccount = ();
|
|
type OnKilledAccount = ();
|
|
type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
impl pallet_utility::Trait 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::Trait 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::Trait 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) * MaximumBlockWeight::get();
|
|
pub const MaxScheduledPerBlock: u32 = 50;
|
|
}
|
|
|
|
impl pallet_scheduler::Trait 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! {
|
|
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS;
|
|
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
|
|
}
|
|
|
|
impl pallet_babe::Trait 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>;
|
|
|
|
type WeightInfo = ();
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const IndexDeposit: Balance = 1 * DOLLARS;
|
|
}
|
|
|
|
impl pallet_indices::Trait 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::Trait for Runtime {
|
|
type MaxLocks = MaxLocks;
|
|
type Balance = Balance;
|
|
type DustRemoval = ();
|
|
type Event = Event;
|
|
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::Trait 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::Trait 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::Trait 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::Trait for Runtime {
|
|
type Event = Event;
|
|
type ValidatorId = <Self as frame_system::Trait>::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::Trait 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 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 = MaximumExtrinsicWeight::get()
|
|
.saturating_sub(BlockExecutionWeight::get())
|
|
.saturating_sub(ExtrinsicBaseWeight::get());
|
|
}
|
|
|
|
impl pallet_staking::Trait for Runtime {
|
|
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 RewardCurve = RewardCurve;
|
|
type NextNewSession = Session;
|
|
type ElectionLookahead = ElectionLookahead;
|
|
type Call = Call;
|
|
type MaxIterations = MaxIterations;
|
|
type MinSolutionScoreBump = MinSolutionScoreBump;
|
|
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
|
|
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 WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
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::Trait 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 cooloff period.
|
|
type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
|
|
type CooloffPeriod = CooloffPeriod;
|
|
type PreimageByteDeposit = PreimageByteDeposit;
|
|
type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
|
|
type Slash = Treasury;
|
|
type Scheduler = Scheduler;
|
|
type PalletsOrigin = OriginCaller;
|
|
type MaxVotes = MaxVotes;
|
|
type WeightInfo = 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::Trait<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;
|
|
pub const VotingBond: Balance = 1 * DOLLARS;
|
|
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::Trait for Runtime {
|
|
type Event = Event;
|
|
type ModuleId = ElectionsPhragmenModuleId;
|
|
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 VotingBond = VotingBond;
|
|
type LoserCandidate = ();
|
|
type BadReport = ();
|
|
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::Trait<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::Trait<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;
|
|
}
|
|
|
|
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::Trait for Runtime {
|
|
type ModuleId = TreasuryModuleId;
|
|
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 Tippers = Elections;
|
|
type TipCountdown = TipCountdown;
|
|
type TipFindersFee = TipFindersFee;
|
|
type TipReportDepositBase = TipReportDepositBase;
|
|
type DataDepositPerByte = DataDepositPerByte;
|
|
type Event = Event;
|
|
type OnSlash = ();
|
|
type ProposalBond = ProposalBond;
|
|
type ProposalBondMinimum = ProposalBondMinimum;
|
|
type SpendPeriod = SpendPeriod;
|
|
type Burn = Burn;
|
|
type BountyDepositBase = BountyDepositBase;
|
|
type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
|
|
type BountyUpdatePeriod = BountyUpdatePeriod;
|
|
type BountyCuratorDeposit = BountyCuratorDeposit;
|
|
type BountyValueMinimum = BountyValueMinimum;
|
|
type MaximumReasonLength = MaximumReasonLength;
|
|
type BurnDestination = ();
|
|
type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub const TombstoneDeposit: Balance = 16 * MILLICENTS;
|
|
pub const RentByteFee: Balance = 4 * MILLICENTS;
|
|
pub const RentDepositOffset: Balance = 1000 * MILLICENTS;
|
|
pub const SurchargeReward: Balance = 150 * MILLICENTS;
|
|
pub const SignedClaimHandicap: u32 = 2;
|
|
pub const MaxDepth: u32 = 32;
|
|
pub const StorageSizeOffset: u32 = 8;
|
|
pub const MaxValueSize: u32 = 16 * 1024;
|
|
}
|
|
|
|
impl pallet_contracts::Trait for Runtime {
|
|
type Time = Timestamp;
|
|
type Randomness = RandomnessCollectiveFlip;
|
|
type Currency = Balances;
|
|
type Event = Event;
|
|
type RentPayment = ();
|
|
type SignedClaimHandicap = SignedClaimHandicap;
|
|
type TombstoneDeposit = TombstoneDeposit;
|
|
type StorageSizeOffset = StorageSizeOffset;
|
|
type RentByteFee = RentByteFee;
|
|
type RentDepositOffset = RentDepositOffset;
|
|
type SurchargeReward = SurchargeReward;
|
|
type MaxDepth = MaxDepth;
|
|
type MaxValueSize = MaxValueSize;
|
|
type WeightPrice = pallet_transaction_payment::Module<Self>;
|
|
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
|
|
}
|
|
|
|
impl pallet_sudo::Trait for Runtime {
|
|
type Event = Event;
|
|
type Call = Call;
|
|
}
|
|
|
|
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)> {
|
|
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| {
|
|
debug::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::Trait for Runtime {
|
|
type AuthorityId = ImOnlineId;
|
|
type Event = Event;
|
|
type SessionDuration = SessionDuration;
|
|
type ReportUnresponsiveness = Offences;
|
|
type UnsignedPriority = ImOnlineUnsignedPriority;
|
|
type WeightInfo = pallet_im_online::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
parameter_types! {
|
|
pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
|
|
}
|
|
|
|
impl pallet_offences::Trait for Runtime {
|
|
type Event = Event;
|
|
type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
|
|
type OnOffenceHandler = Staking;
|
|
type WeightSoftLimit = OffencesWeightSoftLimit;
|
|
}
|
|
|
|
impl pallet_authority_discovery::Trait for Runtime {}
|
|
|
|
impl pallet_grandpa::Trait 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>;
|
|
|
|
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::Trait 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::Trait 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::Trait for Runtime {
|
|
type Event = Event;
|
|
type ModuleId = SocietyModuleId;
|
|
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::Trait for Runtime {
|
|
type Event = Event;
|
|
type Currency = Balances;
|
|
type BlockNumberToBalance = ConvertInto;
|
|
type MinVestedTransfer = MinVestedTransfer;
|
|
type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
|
|
}
|
|
|
|
construct_runtime!(
|
|
pub enum Runtime where
|
|
Block = Block,
|
|
NodeBlock = node_primitives::Block,
|
|
UncheckedExtrinsic = UncheckedExtrinsic
|
|
{
|
|
System: frame_system::{Module, Call, Config, Storage, Event<T>},
|
|
Utility: pallet_utility::{Module, Call, Event},
|
|
Babe: pallet_babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned},
|
|
Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
|
|
Authorship: pallet_authorship::{Module, Call, Storage, Inherent},
|
|
Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
|
|
Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
|
|
TransactionPayment: pallet_transaction_payment::{Module, Storage},
|
|
Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
|
|
Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
|
|
Democracy: pallet_democracy::{Module, Call, Storage, Config, Event<T>},
|
|
Council: pallet_collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
|
|
TechnicalCommittee: pallet_collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
|
|
Elections: pallet_elections_phragmen::{Module, Call, Storage, Event<T>, Config<T>},
|
|
TechnicalMembership: pallet_membership::<Instance1>::{Module, Call, Storage, Event<T>, Config<T>},
|
|
Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned},
|
|
Treasury: pallet_treasury::{Module, Call, Storage, Config, Event<T>},
|
|
Contracts: pallet_contracts::{Module, Call, Config<T>, Storage, Event<T>},
|
|
Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
|
|
ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
|
|
AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
|
|
Offences: pallet_offences::{Module, Call, Storage, Event},
|
|
Historical: pallet_session_historical::{Module},
|
|
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
|
|
Identity: pallet_identity::{Module, Call, Storage, Event<T>},
|
|
Society: pallet_society::{Module, Call, Storage, Event<T>, Config<T>},
|
|
Recovery: pallet_recovery::{Module, Call, Storage, Event<T>},
|
|
Vesting: pallet_vesting::{Module, Call, Storage, Event<T>, Config<T>},
|
|
Scheduler: pallet_scheduler::{Module, Call, Storage, Event<T>},
|
|
Proxy: pallet_proxy::{Module, Call, Storage, Event<T>},
|
|
Multisig: pallet_multisig::{Module, Call, Storage, Event<T>},
|
|
}
|
|
);
|
|
|
|
/// 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, AllModules>;
|
|
|
|
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)
|
|
}
|
|
|
|
fn random_seed() -> <Block as BlockT>::Hash {
|
|
RandomnessCollectiveFlip::random_seed()
|
|
}
|
|
}
|
|
|
|
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: PRIMARY_PROBABILITY,
|
|
genesis_authorities: Babe::authorities(),
|
|
randomness: Babe::randomness(),
|
|
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
|
|
}
|
|
}
|
|
|
|
fn current_epoch_start() -> sp_consensus_babe::SlotNumber {
|
|
Babe::current_epoch_start()
|
|
}
|
|
|
|
fn generate_key_ownership_proof(
|
|
_slot_number: sp_consensus_babe::SlotNumber,
|
|
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>
|
|
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)
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
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 = "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::Module as SessionBench;
|
|
use pallet_offences_benchmarking::Module as OffencesBench;
|
|
use frame_system_benchmarking::Module as SystemBench;
|
|
|
|
impl pallet_session_benchmarking::Trait for Runtime {}
|
|
impl pallet_offences_benchmarking::Trait for Runtime {}
|
|
impl frame_system_benchmarking::Trait 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_babe, Babe);
|
|
add_benchmark!(params, batches, pallet_balances, Balances);
|
|
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_elections_phragmen, Elections);
|
|
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_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_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>();
|
|
}
|
|
}
|