mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 23:07:57 +00:00
Add Statemint (#452)
* Add Statemint * Versioning. * Fixes * Fixes * Fixes * Fixes * Fixes * Benchmarking * kick patch (paritytech/statemin#88) * Westmint Chain Spec (paritytech/statemint#90) * Tidy the common .toml * Update weights * add westmint sudo key comment * Port consensus stuff * fix typo * fix typo ... again * Recognise Westmint Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> Co-authored-by: Bastian Köcher <info@kchr.de>
This commit is contained in:
Generated
+502
-160
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ members = [
|
||||
"client/pov-recovery",
|
||||
"client/service",
|
||||
"pallets/aura-ext",
|
||||
"pallets/collator-selection",
|
||||
"pallets/dmp-queue",
|
||||
"pallets/parachain-system",
|
||||
"pallets/xcm",
|
||||
@@ -20,6 +21,10 @@ members = [
|
||||
"polkadot-parachains/pallets/ping",
|
||||
"polkadot-parachains/rococo-runtime",
|
||||
"polkadot-parachains/shell-runtime",
|
||||
"polkadot-parachains/statemint-common",
|
||||
"polkadot-parachains/statemint-runtime",
|
||||
"polkadot-parachains/statemine-runtime",
|
||||
"polkadot-parachains/westmint-runtime",
|
||||
"test/runtime",
|
||||
"test/runtime-upgrade",
|
||||
"test/client",
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
[package]
|
||||
authors = ['Anonymous']
|
||||
description = 'Simple staking pallet with a fixed stake.'
|
||||
edition = '2018'
|
||||
homepage = 'https://substrate.dev'
|
||||
license = 'Apache-2.0'
|
||||
name = 'pallet-collator-selection'
|
||||
readme = 'README.md'
|
||||
repository = 'https://github.com/paritytech/cumulus/'
|
||||
version = '3.0.0'
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ['x86_64-unknown-linux-gnu']
|
||||
|
||||
[dependencies]
|
||||
log = { version = "0.4.0", default-features = false }
|
||||
codec = { default-features = false, features = ['derive'], package = 'parity-scale-codec', version = '2.0.0' }
|
||||
serde = { version = "1.0.119", default-features = false }
|
||||
sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
sp-staking = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
pallet-authorship = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
pallet-session = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
|
||||
frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
|
||||
[dev-dependencies]
|
||||
sp-core = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
sp-io = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
sp-tracing = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
sp-runtime = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
pallet-timestamp = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
sp-consensus-aura = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '0.9.0' }
|
||||
pallet-balances = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
pallet-aura = { git = 'https://github.com/paritytech/substrate', branch = "master", version = '3.0.0' }
|
||||
|
||||
[features]
|
||||
default = ['std']
|
||||
runtime-benchmarks = [
|
||||
'frame-benchmarking',
|
||||
'frame-support/runtime-benchmarks',
|
||||
'frame-system/runtime-benchmarks',
|
||||
]
|
||||
std = [
|
||||
'codec/std',
|
||||
'log/std',
|
||||
'sp-runtime/std',
|
||||
'sp-staking/std',
|
||||
'sp-std/std',
|
||||
'frame-support/std',
|
||||
'frame-system/std',
|
||||
'frame-benchmarking/std',
|
||||
'pallet-authorship/std',
|
||||
'pallet-session/std',
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
License: Apache-2.0
|
||||
@@ -0,0 +1,190 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Benchmarking setup for pallet-collator-selection
|
||||
|
||||
use super::*;
|
||||
|
||||
#[allow(unused)]
|
||||
use crate::Pallet as CollatorSelection;
|
||||
use sp_std::prelude::*;
|
||||
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller, account};
|
||||
use frame_system::{RawOrigin, EventRecord};
|
||||
use frame_support::{
|
||||
assert_ok,
|
||||
traits::{Currency, Get, EnsureOrigin},
|
||||
};
|
||||
use pallet_authorship::EventHandler;
|
||||
use pallet_session::SessionManager;
|
||||
|
||||
pub type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
const SEED: u32 = 0;
|
||||
|
||||
// TODO: remove if this is given in substrate commit.
|
||||
macro_rules! whitelist {
|
||||
($acc:ident) => {
|
||||
frame_benchmarking::benchmarking::add_to_whitelist(
|
||||
frame_system::Account::<T>::hashed_key_for(&$acc).into()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
fn assert_last_event<T: Config>(generic_event: <T as Config>::Event) {
|
||||
let events = frame_system::Pallet::<T>::events();
|
||||
let system_event: <T as frame_system::Config>::Event = generic_event.into();
|
||||
// compare to the last event record
|
||||
let EventRecord { event, .. } = &events[events.len() - 1];
|
||||
assert_eq!(event, &system_event);
|
||||
}
|
||||
|
||||
fn register_candidates<T: Config>(count: u32) {
|
||||
let candidates = (0..count).map(|c| account("candidate", c, SEED)).collect::<Vec<_>>();
|
||||
assert!(<CandidacyBond<T>>::get() > 0u32.into(), "Bond cannot be zero!");
|
||||
for who in candidates {
|
||||
T::Currency::make_free_balance_be(&who, <CandidacyBond<T>>::get() * 2u32.into());
|
||||
<CollatorSelection<T>>::register_as_candidate(RawOrigin::Signed(who).into()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
benchmarks! {
|
||||
where_clause { where T: pallet_authorship::Config }
|
||||
|
||||
set_invulnerables {
|
||||
let b in 1 .. T::MaxInvulnerables::get();
|
||||
let new_invulnerables = (0..b).map(|c| account("candidate", c, SEED)).collect::<Vec<_>>();
|
||||
let origin = T::UpdateOrigin::successful_origin();
|
||||
}: {
|
||||
assert_ok!(
|
||||
<CollatorSelection<T>>::set_invulnerables(origin, new_invulnerables.clone())
|
||||
);
|
||||
}
|
||||
verify {
|
||||
assert_last_event::<T>(Event::NewInvulnerables(new_invulnerables).into());
|
||||
}
|
||||
|
||||
set_desired_candidates {
|
||||
let max: u32 = 999;
|
||||
let origin = T::UpdateOrigin::successful_origin();
|
||||
}: {
|
||||
assert_ok!(
|
||||
<CollatorSelection<T>>::set_desired_candidates(origin, max.clone())
|
||||
);
|
||||
}
|
||||
verify {
|
||||
assert_last_event::<T>(Event::NewDesiredCandidates(max).into());
|
||||
}
|
||||
|
||||
set_candidacy_bond {
|
||||
let bond: BalanceOf<T> = T::Currency::minimum_balance() * 10u32.into();
|
||||
let origin = T::UpdateOrigin::successful_origin();
|
||||
}: {
|
||||
assert_ok!(
|
||||
<CollatorSelection<T>>::set_candidacy_bond(origin, bond.clone())
|
||||
);
|
||||
}
|
||||
verify {
|
||||
assert_last_event::<T>(Event::NewCandidacyBond(bond).into());
|
||||
}
|
||||
|
||||
// worse case is when we have all the max-candidate slots filled except one, and we fill that
|
||||
// one.
|
||||
register_as_candidate {
|
||||
let c in 1 .. T::MaxCandidates::get();
|
||||
|
||||
<CandidacyBond<T>>::put(T::Currency::minimum_balance());
|
||||
<DesiredCandidates<T>>::put(c + 1);
|
||||
register_candidates::<T>(c);
|
||||
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
let bond: BalanceOf<T> = T::Currency::minimum_balance() * 2u32.into();
|
||||
T::Currency::make_free_balance_be(&caller, bond.clone());
|
||||
|
||||
}: _(RawOrigin::Signed(caller.clone()))
|
||||
verify {
|
||||
assert_last_event::<T>(Event::CandidateAdded(caller, bond / 2u32.into()).into());
|
||||
}
|
||||
|
||||
// worse case is the last candidate leaving.
|
||||
leave_intent {
|
||||
let c in 1 .. T::MaxCandidates::get();
|
||||
<CandidacyBond<T>>::put(T::Currency::minimum_balance());
|
||||
<DesiredCandidates<T>>::put(c);
|
||||
register_candidates::<T>(c);
|
||||
|
||||
let leaving = <Candidates<T>>::get().last().unwrap().who.clone();
|
||||
whitelist!(leaving);
|
||||
}: _(RawOrigin::Signed(leaving.clone()))
|
||||
verify {
|
||||
assert_last_event::<T>(Event::CandidateRemoved(leaving).into());
|
||||
}
|
||||
|
||||
// worse case is paying a non-existing candidate account.
|
||||
note_author {
|
||||
<CandidacyBond<T>>::put(T::Currency::minimum_balance());
|
||||
T::Currency::make_free_balance_be(
|
||||
&<CollatorSelection<T>>::account_id(),
|
||||
T::Currency::minimum_balance() * 4u32.into(),
|
||||
);
|
||||
let author = account("author", 0, SEED);
|
||||
let new_block: T::BlockNumber = 10u32.into();
|
||||
|
||||
frame_system::Pallet::<T>::set_block_number(new_block);
|
||||
assert!(T::Currency::free_balance(&author) == 0u32.into());
|
||||
}: {
|
||||
<CollatorSelection<T> as EventHandler<_, _>>::note_author(author.clone())
|
||||
} verify {
|
||||
assert!(T::Currency::free_balance(&author) > 0u32.into());
|
||||
assert_eq!(frame_system::Pallet::<T>::block_number(), new_block);
|
||||
}
|
||||
|
||||
// worse case is on new session.
|
||||
// TODO review this benchmark
|
||||
new_session {
|
||||
let r in 1 .. T::MaxCandidates::get();
|
||||
let c in 1 .. T::MaxCandidates::get();
|
||||
|
||||
<CandidacyBond<T>>::put(T::Currency::minimum_balance());
|
||||
<DesiredCandidates<T>>::put(c);
|
||||
frame_system::Pallet::<T>::set_block_number(0u32.into());
|
||||
register_candidates::<T>(c);
|
||||
|
||||
let new_block: T::BlockNumber = 1800u32.into();
|
||||
let zero_block: T::BlockNumber = 0u32.into();
|
||||
let candidates = <Candidates<T>>::get();
|
||||
|
||||
let non_removals = c.saturating_sub(r);
|
||||
|
||||
for i in 0..c {
|
||||
<LastAuthoredBlock<T>>::insert(candidates[i as usize].who.clone(), zero_block);
|
||||
}
|
||||
for i in 0..non_removals {
|
||||
<LastAuthoredBlock<T>>::insert(candidates[i as usize].who.clone(), new_block);
|
||||
}
|
||||
|
||||
let pre_length = <Candidates<T>>::get().len();
|
||||
frame_system::Pallet::<T>::set_block_number(new_block);
|
||||
|
||||
assert!(<Candidates<T>>::get().len() == c as usize);
|
||||
|
||||
}: {
|
||||
<CollatorSelection<T> as SessionManager<_>>::new_session(0)
|
||||
} verify {
|
||||
assert!(<Candidates<T>>::get().len() < pre_length);
|
||||
}
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(CollatorSelection, crate::mock::new_test_ext(), crate::mock::Test,);
|
||||
@@ -0,0 +1,437 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Collator Selection pallet.
|
||||
//!
|
||||
//! A pallet to manage collators in a parachain.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The Collator Selection pallet manages the collators of a parachain. **Collation is _not_ a
|
||||
//! secure activity** and this pallet does not implement any game-theoretic mechanisms to meet BFT
|
||||
//! safety assumptions of the chosen set.
|
||||
//!
|
||||
//! ## Terminology
|
||||
//!
|
||||
//! - Collator: A parachain block producer.
|
||||
//! - Bond: An amount of `Balance` _reserved_ for candidate registration.
|
||||
//! - Invulnerable: An account guaranteed to be in the collator set.
|
||||
//!
|
||||
//! ## Implementation
|
||||
//!
|
||||
//! The final [`Collators`] are aggregated from two individual lists:
|
||||
//!
|
||||
//! 1. [`Invulnerables`]: a set of collators appointed by governance. These accounts will always be
|
||||
//! collators.
|
||||
//! 2. [`Candidates`]: these are *candidates to the collation task* and may or may not be elected as
|
||||
//! a final collator.
|
||||
//!
|
||||
//! The current implementation resolves congestion of [`Candidates`] in a first-come-first-serve
|
||||
//! manner.
|
||||
//!
|
||||
//! ### Rewards
|
||||
//!
|
||||
//! The Collator Selection pallet maintains an on-chain account (the "Pot"). In each block, the
|
||||
//! collator who authored it receives:
|
||||
//!
|
||||
//! - Half the value of the Pot.
|
||||
//! - Half the value of the transaction fees within the block. The other half of the transaction
|
||||
//! fees are deposited into the Pot.
|
||||
//!
|
||||
//! To initiate rewards an ED needs to be transferred to the pot address.
|
||||
//!
|
||||
//! Note: Eventually the Pot distribution may be modified as discussed in
|
||||
//! [this issue](https://github.com/paritytech/statemint/issues/21#issuecomment-810481073).
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
pub use pallet::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarking;
|
||||
pub mod weights;
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use frame_support::{
|
||||
dispatch::DispatchResultWithPostInfo,
|
||||
pallet_prelude::*,
|
||||
inherent::Vec,
|
||||
traits::{
|
||||
Currency, ReservableCurrency, EnsureOrigin, ExistenceRequirement::KeepAlive,
|
||||
},
|
||||
PalletId,
|
||||
};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use frame_system::Config as SystemConfig;
|
||||
use frame_support::{
|
||||
sp_runtime::{
|
||||
RuntimeDebug,
|
||||
traits::{AccountIdConversion, CheckedSub, Zero, Saturating},
|
||||
},
|
||||
weights::DispatchClass,
|
||||
};
|
||||
use core::ops::Div;
|
||||
use pallet_session::SessionManager;
|
||||
use sp_staking::SessionIndex;
|
||||
pub use crate::weights::WeightInfo;
|
||||
|
||||
type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as SystemConfig>::AccountId>>::Balance;
|
||||
|
||||
/// A convertor from collators id. Since this pallet does not have stash/controller, this is
|
||||
/// just identity.
|
||||
pub struct IdentityCollator;
|
||||
impl<T> sp_runtime::traits::Convert<T, Option<T>> for IdentityCollator {
|
||||
fn convert(t: T) -> Option<T> {
|
||||
Some(t)
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure the pallet by specifying the parameters and types on which it depends.
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
/// Overarching event type.
|
||||
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
|
||||
|
||||
/// The currency mechanism.
|
||||
type Currency: ReservableCurrency<Self::AccountId>;
|
||||
|
||||
/// Origin that can dictate updating parameters of this pallet.
|
||||
type UpdateOrigin: EnsureOrigin<Self::Origin>;
|
||||
|
||||
/// Account Identifier from which the internal Pot is generated.
|
||||
type PotId: Get<PalletId>;
|
||||
|
||||
/// Maximum number of candidates that we should have. This is used for benchmarking and is not
|
||||
/// enforced.
|
||||
///
|
||||
/// This does not take into account the invulnerables.
|
||||
type MaxCandidates: Get<u32>;
|
||||
|
||||
/// Maximum number of invulnerables.
|
||||
///
|
||||
/// Used only for benchmarking.
|
||||
type MaxInvulnerables: Get<u32>;
|
||||
|
||||
// Will be kicked if block is not produced in threshold.
|
||||
type KickThreshold: Get<Self::BlockNumber>;
|
||||
|
||||
/// The weight information of this pallet.
|
||||
type WeightInfo: WeightInfo;
|
||||
}
|
||||
|
||||
/// Basic information about a collation candidate.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
|
||||
pub struct CandidateInfo<AccountId, Balance> {
|
||||
/// Account identifier.
|
||||
pub who: AccountId,
|
||||
/// Reserved deposit.
|
||||
pub deposit: Balance,
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
/// The invulnerable, fixed collators.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn invulnerables)]
|
||||
pub type Invulnerables<T: Config> = StorageValue<_, Vec<T::AccountId>, ValueQuery>;
|
||||
|
||||
/// The (community, limited) collation candidates.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn candidates)]
|
||||
pub type Candidates<T: Config> = StorageValue<
|
||||
_,
|
||||
Vec<CandidateInfo<T::AccountId, BalanceOf<T>>>,
|
||||
ValueQuery,
|
||||
>;
|
||||
|
||||
/// Last block authored by collator.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn last_authored_block)]
|
||||
pub type LastAuthoredBlock<T: Config> = StorageMap<_, Twox64Concat, T::AccountId, T::BlockNumber, ValueQuery>;
|
||||
|
||||
/// Desired number of candidates.
|
||||
///
|
||||
/// This should ideally always be less than [`Config::MaxCandidates`] for weights to be correct.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn desired_candidates)]
|
||||
pub type DesiredCandidates<T> = StorageValue<_, u32, ValueQuery>;
|
||||
|
||||
/// Fixed deposit bond for each candidate.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn candidacy_bond)]
|
||||
pub type CandidacyBond<T> = StorageValue<_, BalanceOf<T>, ValueQuery>;
|
||||
|
||||
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig<T: Config> {
|
||||
pub invulnerables: Vec<T::AccountId>,
|
||||
pub candidacy_bond: BalanceOf<T>,
|
||||
pub desired_candidates: u32,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Config> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
invulnerables: Default::default(),
|
||||
candidacy_bond: Default::default(),
|
||||
desired_candidates: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
|
||||
fn build(&self) {
|
||||
|
||||
let duplicate_invulnerables = self.invulnerables.iter().collect::<std::collections::BTreeSet<_>>();
|
||||
assert!(duplicate_invulnerables.len() == self.invulnerables.len(), "duplicate invulnerables in genesis.");
|
||||
|
||||
assert!(
|
||||
T::MaxInvulnerables::get() >= (self.invulnerables.len() as u32),
|
||||
"genesis invulnerables are more than T::MaxInvulnerables",
|
||||
);
|
||||
assert!(
|
||||
T::MaxCandidates::get() >= self.desired_candidates,
|
||||
"genesis desired_candidates are more than T::MaxCandidates",
|
||||
);
|
||||
|
||||
<DesiredCandidates<T>>::put(&self.desired_candidates);
|
||||
<CandidacyBond<T>>::put(&self.candidacy_bond);
|
||||
<Invulnerables<T>>::put(&self.invulnerables);
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::metadata(T::AccountId = "AccountId", BalanceOf<T> = "Balance")]
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
NewInvulnerables(Vec<T::AccountId>),
|
||||
NewDesiredCandidates(u32),
|
||||
NewCandidacyBond(BalanceOf<T>),
|
||||
CandidateAdded(T::AccountId, BalanceOf<T>),
|
||||
CandidateRemoved(T::AccountId),
|
||||
}
|
||||
|
||||
// Errors inform users that something went wrong.
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
TooManyCandidates,
|
||||
Unknown,
|
||||
Permission,
|
||||
AlreadyCandidate,
|
||||
NotCandidate,
|
||||
AlreadyInvulnerable,
|
||||
InvalidProof,
|
||||
}
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
#[pallet::weight(T::WeightInfo::set_invulnerables(new.len() as u32))]
|
||||
pub fn set_invulnerables(
|
||||
origin: OriginFor<T>,
|
||||
new: Vec<T::AccountId>,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
T::UpdateOrigin::ensure_origin(origin)?;
|
||||
// we trust origin calls, this is just a for more accurate benchmarking
|
||||
if (new.len() as u32) > T::MaxInvulnerables::get() {
|
||||
log::warn!(
|
||||
"invulnerables > T::MaxInvulnerables; you might need to run benchmarks again"
|
||||
);
|
||||
}
|
||||
<Invulnerables<T>>::put(&new);
|
||||
Self::deposit_event(Event::NewInvulnerables(new));
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
#[pallet::weight(T::WeightInfo::set_desired_candidates())]
|
||||
pub fn set_desired_candidates(origin: OriginFor<T>, max: u32) -> DispatchResultWithPostInfo {
|
||||
T::UpdateOrigin::ensure_origin(origin)?;
|
||||
// we trust origin calls, this is just a for more accurate benchmarking
|
||||
if max > T::MaxCandidates::get() {
|
||||
log::warn!(
|
||||
"max > T::MaxCandidates; you might need to run benchmarks again"
|
||||
);
|
||||
}
|
||||
<DesiredCandidates<T>>::put(&max);
|
||||
Self::deposit_event(Event::NewDesiredCandidates(max));
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
#[pallet::weight(T::WeightInfo::set_candidacy_bond())]
|
||||
pub fn set_candidacy_bond(origin: OriginFor<T>, bond: BalanceOf<T>) -> DispatchResultWithPostInfo {
|
||||
T::UpdateOrigin::ensure_origin(origin)?;
|
||||
<CandidacyBond<T>>::put(&bond);
|
||||
Self::deposit_event(Event::NewCandidacyBond(bond));
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
#[pallet::weight(T::WeightInfo::register_as_candidate(T::MaxCandidates::get()))]
|
||||
pub fn register_as_candidate(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
// ensure we are below limit.
|
||||
let length = <Candidates<T>>::decode_len().unwrap_or_default();
|
||||
ensure!((length as u32) < Self::desired_candidates(), Error::<T>::TooManyCandidates);
|
||||
ensure!(!Self::invulnerables().contains(&who), Error::<T>::AlreadyInvulnerable);
|
||||
|
||||
let deposit = Self::candidacy_bond();
|
||||
// First authored block is current block plus kick threshold to handle session delay
|
||||
let incoming = CandidateInfo { who: who.clone(), deposit };
|
||||
|
||||
let current_count =
|
||||
<Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {
|
||||
if candidates.into_iter().any(|candidate| candidate.who == who) {
|
||||
Err(Error::<T>::AlreadyCandidate)?
|
||||
} else {
|
||||
T::Currency::reserve(&who, deposit)?;
|
||||
candidates.push(incoming);
|
||||
<LastAuthoredBlock<T>>::insert(who.clone(), frame_system::Pallet::<T>::block_number() + T::KickThreshold::get());
|
||||
Ok(candidates.len())
|
||||
}
|
||||
})?;
|
||||
|
||||
Self::deposit_event(Event::CandidateAdded(who, deposit));
|
||||
Ok(Some(T::WeightInfo::register_as_candidate(current_count as u32)).into())
|
||||
}
|
||||
|
||||
#[pallet::weight(T::WeightInfo::leave_intent(T::MaxCandidates::get()))]
|
||||
pub fn leave_intent(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
let current_count = Self::try_remove_candidate(&who)?;
|
||||
|
||||
Ok(Some(T::WeightInfo::leave_intent(current_count as u32)).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Get a unique, inaccessible account id from the `PotId`.
|
||||
pub fn account_id() -> T::AccountId {
|
||||
T::PotId::get().into_account()
|
||||
}
|
||||
/// Removes a candidate if they exist and sends them back their deposit
|
||||
fn try_remove_candidate(who: &T::AccountId) -> Result<usize, DispatchError> {
|
||||
let current_count = <Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {
|
||||
let index = candidates.iter().position(|candidate| candidate.who == *who).ok_or(Error::<T>::NotCandidate)?;
|
||||
T::Currency::unreserve(&who, candidates[index].deposit);
|
||||
candidates.remove(index);
|
||||
<LastAuthoredBlock<T>>::remove(who.clone());
|
||||
Ok(candidates.len())
|
||||
});
|
||||
Self::deposit_event(Event::CandidateRemoved(who.clone()));
|
||||
current_count
|
||||
}
|
||||
|
||||
/// Assemble the current set of candidates and invulnerables into the next collator set.
|
||||
///
|
||||
/// This is done on the fly, as frequent as we are told to do so, as the session manager.
|
||||
pub fn assemble_collators(candidates: Vec<T::AccountId>) -> Vec<T::AccountId> {
|
||||
let mut collators = Self::invulnerables();
|
||||
collators.extend(
|
||||
candidates.into_iter().collect::<Vec<_>>(),
|
||||
);
|
||||
collators
|
||||
}
|
||||
/// Kicks out and candidates that did not produce a block in the kick threshold.
|
||||
pub fn kick_stale_candidates(candidates: Vec<CandidateInfo<T::AccountId, BalanceOf<T>>>) -> Vec<T::AccountId> {
|
||||
let now = frame_system::Pallet::<T>::block_number();
|
||||
let kick_threshold = T::KickThreshold::get();
|
||||
let new_candidates = candidates.into_iter().filter_map(|c| {
|
||||
let last_block = <LastAuthoredBlock<T>>::get(c.who.clone());
|
||||
let since_last = now.saturating_sub(last_block);
|
||||
if since_last < kick_threshold {
|
||||
Some(c.who)
|
||||
} else {
|
||||
let outcome = Self::try_remove_candidate(&c.who);
|
||||
if let Err(why) = outcome {
|
||||
log::warn!("Failed to remove candidate {:?}", why);
|
||||
debug_assert!(false, "failed to remove candidate {:?}", why);
|
||||
}
|
||||
None
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
new_candidates
|
||||
}
|
||||
}
|
||||
|
||||
/// Keep track of number of authored blocks per authority, uncles are counted as well since
|
||||
/// they're a valid proof of being online.
|
||||
impl<T: Config + pallet_authorship::Config>
|
||||
pallet_authorship::EventHandler<T::AccountId, T::BlockNumber> for Pallet<T>
|
||||
{
|
||||
fn note_author(author: T::AccountId) {
|
||||
let pot = Self::account_id();
|
||||
// assumes an ED will be sent to pot.
|
||||
let reward = T::Currency::free_balance(&pot).checked_sub(&T::Currency::minimum_balance()).unwrap_or_else(Zero::zero).div(2u32.into());
|
||||
// `reward` is half of pot account minus ED, this should never fail.
|
||||
let _success = T::Currency::transfer(&pot, &author, reward, KeepAlive);
|
||||
debug_assert!(_success.is_ok());
|
||||
<LastAuthoredBlock<T>>::insert(author, frame_system::Pallet::<T>::block_number());
|
||||
|
||||
frame_system::Pallet::<T>::register_extra_weight_unchecked(
|
||||
T::WeightInfo::note_author(),
|
||||
DispatchClass::Mandatory,
|
||||
);
|
||||
}
|
||||
|
||||
fn note_uncle(_author: T::AccountId, _age: T::BlockNumber) {
|
||||
//TODO can we ignore this?
|
||||
}
|
||||
}
|
||||
|
||||
/// Play the role of the session manager.
|
||||
impl<T: Config> SessionManager<T::AccountId> for Pallet<T> {
|
||||
fn new_session(index: SessionIndex) -> Option<Vec<T::AccountId>> {
|
||||
log::info!(
|
||||
"assembling new collators for new session {} at #{:?}",
|
||||
index,
|
||||
<frame_system::Pallet<T>>::block_number(),
|
||||
);
|
||||
|
||||
let candidates = Self::candidates();
|
||||
let candidates_len_before = candidates.len();
|
||||
let active_candidates = Self::kick_stale_candidates(candidates);
|
||||
let active_candidates_len = active_candidates.len();
|
||||
let result = Self::assemble_collators(active_candidates);
|
||||
let removed = candidates_len_before - active_candidates_len;
|
||||
|
||||
frame_system::Pallet::<T>::register_extra_weight_unchecked(
|
||||
T::WeightInfo::new_session(candidates_len_before as u32, removed as u32),
|
||||
DispatchClass::Mandatory,
|
||||
);
|
||||
Some(result)
|
||||
}
|
||||
fn start_session(_: SessionIndex) {
|
||||
// we don't care.
|
||||
}
|
||||
fn end_session(_: SessionIndex) {
|
||||
// we don't care.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use super::*;
|
||||
use crate as collator_selection;
|
||||
use sp_core::H256;
|
||||
use frame_support::{
|
||||
parameter_types, ord_parameter_types,
|
||||
traits::{FindAuthor, GenesisBuild},
|
||||
PalletId
|
||||
};
|
||||
use sp_runtime::{
|
||||
RuntimeAppPublic,
|
||||
traits::{BlakeTwo256, IdentityLookup, OpaqueKeys},
|
||||
testing::{Header, UintAuthorityId},
|
||||
};
|
||||
use frame_system::{EnsureSignedBy};
|
||||
use frame_system as system;
|
||||
|
||||
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
|
||||
type Block = frame_system::mocking::MockBlock<Test>;
|
||||
|
||||
// Configure a mock runtime to test the pallet.
|
||||
frame_support::construct_runtime!(
|
||||
pub enum Test where
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
{
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
|
||||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
|
||||
Aura: pallet_aura::{Pallet, Call, Storage, Config<T>},
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||
CollatorSelection: collator_selection::{Pallet, Call, Storage, Event<T>},
|
||||
Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent},
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const SS58Prefix: u8 = 42;
|
||||
}
|
||||
|
||||
impl system::Config for Test {
|
||||
type BaseCallFilter = ();
|
||||
type BlockWeights = ();
|
||||
type BlockLength = ();
|
||||
type DbWeight = ();
|
||||
type Origin = Origin;
|
||||
type Call = Call;
|
||||
type Index = u64;
|
||||
type BlockNumber = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = pallet_balances::AccountData<u64>;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: u64 = 5;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Test {
|
||||
type Balance = u64;
|
||||
type Event = Event;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
type WeightInfo = ();
|
||||
type MaxLocks = ();
|
||||
}
|
||||
|
||||
pub struct Author4;
|
||||
impl FindAuthor<u64> for Author4 {
|
||||
fn find_author<'a, I>(_digests: I) -> Option<u64>
|
||||
where I: 'a + IntoIterator<Item = (frame_support::ConsensusEngineId, &'a [u8])>,
|
||||
{
|
||||
Some(4)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_authorship::Config for Test {
|
||||
type FindAuthor = Author4;
|
||||
type UncleGenerations = ();
|
||||
type FilterUncle = ();
|
||||
type EventHandler = CollatorSelection;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MinimumPeriod: u64 = 1;
|
||||
}
|
||||
|
||||
impl pallet_timestamp::Config for Test {
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = Aura;
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
impl pallet_aura::Config for Test {
|
||||
type AuthorityId = sp_consensus_aura::sr25519::AuthorityId;
|
||||
}
|
||||
|
||||
sp_runtime::impl_opaque_keys! {
|
||||
pub struct MockSessionKeys {
|
||||
// a key for aura authoring
|
||||
pub aura: UintAuthorityId,
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UintAuthorityId> for MockSessionKeys {
|
||||
fn from(aura: sp_runtime::testing::UintAuthorityId) -> Self {
|
||||
Self { aura }
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub static SessionHandlerCollators: Vec<u64> = vec![];
|
||||
pub static SessionChangeBlock: u64 = 0;
|
||||
}
|
||||
|
||||
pub struct TestSessionHandler;
|
||||
impl pallet_session::SessionHandler<u64> for TestSessionHandler {
|
||||
const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[UintAuthorityId::ID];
|
||||
fn on_genesis_session<Ks: OpaqueKeys>(keys: &[(u64, Ks)]) {
|
||||
SessionHandlerCollators::set(keys.into_iter().map(|(a, _)| *a).collect::<Vec<_>>())
|
||||
}
|
||||
fn on_new_session<Ks: OpaqueKeys>(_: bool, keys: &[(u64, Ks)], _: &[(u64, Ks)]) {
|
||||
SessionChangeBlock::set(System::block_number());
|
||||
dbg!(keys.len());
|
||||
SessionHandlerCollators::set(keys.into_iter().map(|(a, _)| *a).collect::<Vec<_>>())
|
||||
}
|
||||
fn on_before_session_ending() {}
|
||||
fn on_disabled(_: usize) {}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const Offset: u64 = 0;
|
||||
pub const Period: u64 = 10;
|
||||
}
|
||||
|
||||
impl pallet_session::Config for Test {
|
||||
type Event = Event;
|
||||
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||
// we don't have stash and controller, thus we don't need the convert as well.
|
||||
type ValidatorIdOf = IdentityCollator;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionManager = CollatorSelection;
|
||||
type SessionHandler = TestSessionHandler;
|
||||
type Keys = MockSessionKeys;
|
||||
type DisabledValidatorsThreshold = ();
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
ord_parameter_types! {
|
||||
pub const RootAccount: u64 = 777;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const PotId: PalletId = PalletId(*b"PotStake");
|
||||
pub const MaxCandidates: u32 = 20;
|
||||
pub const MaxInvulnerables: u32 = 20;
|
||||
}
|
||||
|
||||
impl Config for Test {
|
||||
type Event = Event;
|
||||
type Currency = Balances;
|
||||
type UpdateOrigin = EnsureSignedBy<RootAccount, u64>;
|
||||
type PotId = PotId;
|
||||
type MaxCandidates = MaxCandidates;
|
||||
type MaxInvulnerables = MaxInvulnerables;
|
||||
type KickThreshold = Period;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
pub fn new_test_ext() -> sp_io::TestExternalities {
|
||||
sp_tracing::try_init_simple();
|
||||
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
|
||||
let invulnerables = vec![1, 2];
|
||||
let keys = invulnerables.iter().map(|i|
|
||||
(
|
||||
*i,
|
||||
*i,
|
||||
MockSessionKeys { aura: UintAuthorityId(*i) },
|
||||
)
|
||||
).collect::<Vec<_>>();
|
||||
|
||||
let balances = pallet_balances::GenesisConfig::<Test> {
|
||||
balances: vec![
|
||||
(1, 100),
|
||||
(2, 100),
|
||||
(3, 100),
|
||||
(4, 100),
|
||||
(5, 100),
|
||||
],
|
||||
};
|
||||
let collator_selection = collator_selection::GenesisConfig::<Test> {
|
||||
desired_candidates: 2,
|
||||
candidacy_bond: 10,
|
||||
invulnerables,
|
||||
};
|
||||
let session = pallet_session::GenesisConfig::<Test> { keys };
|
||||
balances.assimilate_storage(&mut t).unwrap();
|
||||
// collator selection must be initialized before session.
|
||||
collator_selection.assimilate_storage(&mut t).unwrap();
|
||||
session.assimilate_storage(&mut t).unwrap();
|
||||
|
||||
t.into()
|
||||
}
|
||||
|
||||
pub fn initialize_to_block(n: u64) {
|
||||
for i in System::block_number()+1..=n {
|
||||
System::set_block_number(i);
|
||||
<AllPallets as frame_support::traits::OnInitialize<u64>>::on_initialize(i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
use crate as collator_selection;
|
||||
use crate::{mock::*, Error, CandidateInfo};
|
||||
use frame_support::{
|
||||
assert_noop, assert_ok,
|
||||
traits::{OnInitialize, Currency, GenesisBuild},
|
||||
};
|
||||
use sp_runtime::traits::BadOrigin;
|
||||
use pallet_balances::Error as BalancesError;
|
||||
|
||||
#[test]
|
||||
fn basic_setup_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_eq!(CollatorSelection::desired_candidates(), 2);
|
||||
assert_eq!(CollatorSelection::candidacy_bond(), 10);
|
||||
|
||||
assert!(CollatorSelection::candidates().is_empty());
|
||||
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_should_set_invulnerables() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let new_set = vec![1, 2, 3, 4];
|
||||
assert_ok!(CollatorSelection::set_invulnerables(
|
||||
Origin::signed(RootAccount::get()),
|
||||
new_set.clone()
|
||||
));
|
||||
assert_eq!(CollatorSelection::invulnerables(), new_set);
|
||||
|
||||
// cannot set with non-root.
|
||||
assert_noop!(
|
||||
CollatorSelection::set_invulnerables(Origin::signed(1), new_set.clone()),
|
||||
BadOrigin
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_desired_candidates_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// given
|
||||
assert_eq!(CollatorSelection::desired_candidates(), 2);
|
||||
|
||||
// can set
|
||||
assert_ok!(CollatorSelection::set_desired_candidates(Origin::signed(RootAccount::get()), 7));
|
||||
assert_eq!(CollatorSelection::desired_candidates(), 7);
|
||||
|
||||
// rejects bad origin
|
||||
assert_noop!(CollatorSelection::set_desired_candidates(Origin::signed(1), 8), BadOrigin);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_candidacy_bond() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// given
|
||||
assert_eq!(CollatorSelection::candidacy_bond(), 10);
|
||||
|
||||
// can set
|
||||
assert_ok!(CollatorSelection::set_candidacy_bond(Origin::signed(RootAccount::get()), 7));
|
||||
assert_eq!(CollatorSelection::candidacy_bond(), 7);
|
||||
|
||||
// rejects bad origin.
|
||||
assert_noop!(CollatorSelection::set_candidacy_bond(Origin::signed(1), 8), BadOrigin);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_register_candidate_if_too_many() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// reset desired candidates:
|
||||
<crate::DesiredCandidates<Test>>::put(0);
|
||||
|
||||
// can't accept anyone anymore.
|
||||
assert_noop!(
|
||||
CollatorSelection::register_as_candidate(Origin::signed(3)),
|
||||
Error::<Test>::TooManyCandidates,
|
||||
);
|
||||
|
||||
// reset desired candidates:
|
||||
<crate::DesiredCandidates<Test>>::put(1);
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(4)));
|
||||
|
||||
// but no more
|
||||
assert_noop!(
|
||||
CollatorSelection::register_as_candidate(Origin::signed(5)),
|
||||
Error::<Test>::TooManyCandidates,
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_register_as_candidate_if_invulnerable() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
|
||||
|
||||
// can't 1 because it is invulnerable.
|
||||
assert_noop!(
|
||||
CollatorSelection::register_as_candidate(Origin::signed(1)),
|
||||
Error::<Test>::AlreadyInvulnerable,
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_register_dupe_candidate() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// can add 3 as candidate
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(3)));
|
||||
let addition = CandidateInfo { who: 3, deposit: 10 };
|
||||
assert_eq!(CollatorSelection::candidates(), vec![addition]);
|
||||
assert_eq!(CollatorSelection::last_authored_block(3), 10);
|
||||
assert_eq!(Balances::free_balance(3), 90);
|
||||
|
||||
// but no more
|
||||
assert_noop!(
|
||||
CollatorSelection::register_as_candidate(Origin::signed(3)),
|
||||
Error::<Test>::AlreadyCandidate,
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_register_as_candidate_if_poor() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_eq!(Balances::free_balance(&3), 100);
|
||||
assert_eq!(Balances::free_balance(&33), 0);
|
||||
|
||||
// works
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(3)));
|
||||
|
||||
// poor
|
||||
assert_noop!(
|
||||
CollatorSelection::register_as_candidate(Origin::signed(33)),
|
||||
BalancesError::<Test>::InsufficientBalance,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_as_candidate_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// given
|
||||
assert_eq!(CollatorSelection::desired_candidates(), 2);
|
||||
assert_eq!(CollatorSelection::candidacy_bond(), 10);
|
||||
assert_eq!(CollatorSelection::candidates(), vec![]);
|
||||
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
|
||||
|
||||
// take two endowed, non-invulnerables accounts.
|
||||
assert_eq!(Balances::free_balance(&3), 100);
|
||||
assert_eq!(Balances::free_balance(&4), 100);
|
||||
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(3)));
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(4)));
|
||||
|
||||
assert_eq!(Balances::free_balance(&3), 90);
|
||||
assert_eq!(Balances::free_balance(&4), 90);
|
||||
|
||||
assert_eq!(CollatorSelection::candidates().len(), 2);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leave_intent() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// register a candidate.
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(3)));
|
||||
assert_eq!(Balances::free_balance(3), 90);
|
||||
|
||||
// cannot leave if not candidate.
|
||||
assert_noop!(
|
||||
CollatorSelection::leave_intent(Origin::signed(4)),
|
||||
Error::<Test>::NotCandidate
|
||||
);
|
||||
|
||||
// bond is returned
|
||||
assert_ok!(CollatorSelection::leave_intent(Origin::signed(3)));
|
||||
assert_eq!(Balances::free_balance(3), 100);
|
||||
assert_eq!(CollatorSelection::last_authored_block(3), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authorship_event_handler() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// put 100 in the pot + 5 for ED
|
||||
Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);
|
||||
|
||||
// 4 is the default author.
|
||||
assert_eq!(Balances::free_balance(4), 100);
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(4)));
|
||||
// triggers `note_author`
|
||||
Authorship::on_initialize(1);
|
||||
|
||||
|
||||
let collator = CandidateInfo {
|
||||
who: 4,
|
||||
deposit: 10,
|
||||
};
|
||||
|
||||
assert_eq!(CollatorSelection::candidates(), vec![collator]);
|
||||
assert_eq!(CollatorSelection::last_authored_block(4), 0);
|
||||
|
||||
// half of the pot goes to the collator who's the author (4 in tests).
|
||||
assert_eq!(Balances::free_balance(4), 140);
|
||||
// half + ED stays.
|
||||
assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fees_edgecases() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Nothing panics, no reward when no ED in balance
|
||||
Authorship::on_initialize(1);
|
||||
// put some money into the pot at ED
|
||||
Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);
|
||||
// 4 is the default author.
|
||||
assert_eq!(Balances::free_balance(4), 100);
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(4)));
|
||||
// triggers `note_author`
|
||||
Authorship::on_initialize(1);
|
||||
|
||||
|
||||
let collator = CandidateInfo {
|
||||
who: 4,
|
||||
deposit: 10,
|
||||
};
|
||||
|
||||
assert_eq!(CollatorSelection::candidates(), vec![collator]);
|
||||
assert_eq!(CollatorSelection::last_authored_block(4), 0);
|
||||
// Nothing received
|
||||
assert_eq!(Balances::free_balance(4), 90);
|
||||
// all fee stays
|
||||
assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_management_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
initialize_to_block(1);
|
||||
|
||||
assert_eq!(SessionChangeBlock::get(), 0);
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);
|
||||
|
||||
initialize_to_block(4);
|
||||
|
||||
assert_eq!(SessionChangeBlock::get(), 0);
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);
|
||||
|
||||
// add a new collator
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(3)));
|
||||
|
||||
// session won't see this.
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);
|
||||
// but we have a new candidate.
|
||||
assert_eq!(CollatorSelection::candidates().len(), 1);
|
||||
|
||||
initialize_to_block(10);
|
||||
assert_eq!(SessionChangeBlock::get(), 10);
|
||||
// pallet-session has 1 session delay; current validators are the same.
|
||||
assert_eq!(Session::validators(), vec![1, 2]);
|
||||
// queued ones are changed, and now we have 3.
|
||||
assert_eq!(Session::queued_keys().len(), 3);
|
||||
// session handlers (aura, et. al.) cannot see this yet.
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);
|
||||
|
||||
initialize_to_block(20);
|
||||
assert_eq!(SessionChangeBlock::get(), 20);
|
||||
// changed are now reflected to session handlers.
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kick_mechanism() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// add a new collator
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(3)));
|
||||
assert_ok!(CollatorSelection::register_as_candidate(Origin::signed(4)));
|
||||
initialize_to_block(10);
|
||||
assert_eq!(CollatorSelection::candidates().len(), 2);
|
||||
initialize_to_block(20);
|
||||
assert_eq!(SessionChangeBlock::get(), 20);
|
||||
// 4 authored this block, gets to stay 3 was kicked
|
||||
assert_eq!(CollatorSelection::candidates().len(), 1);
|
||||
// 3 will be kicked after 1 session delay
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);
|
||||
let collator = CandidateInfo {
|
||||
who: 4,
|
||||
deposit: 10,
|
||||
};
|
||||
assert_eq!(CollatorSelection::candidates(), vec![collator]);
|
||||
assert_eq!(CollatorSelection::last_authored_block(4), 20);
|
||||
initialize_to_block(30);
|
||||
// 3 gets kicked after 1 session delay
|
||||
assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);
|
||||
// kicked collator gets funds back
|
||||
assert_eq!(Balances::free_balance(3), 100);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
#[should_panic = "duplicate invulnerables in genesis."]
|
||||
fn cannot_set_genesis_value_twice() {
|
||||
sp_tracing::try_init_simple();
|
||||
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
|
||||
let invulnerables = vec![1, 1];
|
||||
|
||||
let collator_selection = collator_selection::GenesisConfig::<Test> {
|
||||
desired_candidates: 2,
|
||||
candidacy_bond: 10,
|
||||
invulnerables,
|
||||
};
|
||||
// collator selection must be initialized before session.
|
||||
collator_selection.assimilate_storage(&mut t).unwrap();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
// The weight info trait for `pallet_collator_selection`.
|
||||
pub trait WeightInfo {
|
||||
fn set_invulnerables(_b: u32) -> Weight;
|
||||
fn set_desired_candidates() -> Weight;
|
||||
fn set_candidacy_bond() -> Weight;
|
||||
fn register_as_candidate(_c: u32) -> Weight;
|
||||
fn leave_intent(_c: u32) -> Weight;
|
||||
fn note_author() -> Weight;
|
||||
fn new_session(_c: u32, _r: u32) -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for pallet_collator_selection using the Substrate node and recommended hardware.
|
||||
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
fn set_invulnerables(b: u32, ) -> Weight {
|
||||
(18_563_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((68_000 as Weight).saturating_mul(b as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_desired_candidates() -> Weight {
|
||||
(16_363_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_candidacy_bond() -> Weight {
|
||||
(16_840_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn register_as_candidate(c: u32, ) -> Weight {
|
||||
(71_196_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((198_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn leave_intent(c: u32, ) -> Weight {
|
||||
(55_336_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((151_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn note_author() -> Weight {
|
||||
(71_461_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn new_session(r: u32, c: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((109_961_000 as Weight).saturating_mul(r as Weight))
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((151_952_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
fn set_invulnerables(b: u32, ) -> Weight {
|
||||
(18_563_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((68_000 as Weight).saturating_mul(b as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_desired_candidates() -> Weight {
|
||||
(16_363_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_candidacy_bond() -> Weight {
|
||||
(16_840_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn register_as_candidate(c: u32, ) -> Weight {
|
||||
(71_196_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((198_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn leave_intent(c: u32, ) -> Weight {
|
||||
(55_336_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((151_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn note_author() -> Weight {
|
||||
(71_461_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn new_session(r: u32, c: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((109_961_000 as Weight).saturating_mul(r as Weight))
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((151_952_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,19 @@ codec = { package = "parity-scale-codec", version = "2.0.0" }
|
||||
structopt = "0.3.3"
|
||||
serde = { version = "1.0.101", features = ["derive"] }
|
||||
hex-literal = "0.2.1"
|
||||
async-trait = "0.1.42"
|
||||
|
||||
# Parachain runtimes
|
||||
rococo-parachain-runtime = { package = "cumulus-rococo-parachain-runtime", path = "rococo-runtime" }
|
||||
shell-runtime = { package = "cumulus-shell-runtime", path = "shell-runtime" }
|
||||
statemint-runtime = { path = "statemint-runtime" }
|
||||
statemine-runtime = { path = "statemine-runtime" }
|
||||
westmint-runtime = { path = "westmint-runtime" }
|
||||
statemint-common = { path = "statemint-common" }
|
||||
|
||||
# Substrate dependencies
|
||||
frame-benchmarking = { git = 'https://github.com/paritytech/substrate', branch = "master" }
|
||||
frame-benchmarking-cli = { git = 'https://github.com/paritytech/substrate', branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
@@ -75,6 +82,8 @@ polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "m
|
||||
polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
@@ -95,3 +104,12 @@ polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch
|
||||
pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
runtime-benchmarks = [
|
||||
'polkadot-service/runtime-benchmarks',
|
||||
'statemint-runtime/runtime-benchmarks',
|
||||
'statemine-runtime/runtime-benchmarks',
|
||||
'westmint-runtime/runtime-benchmarks',
|
||||
]
|
||||
|
||||
Executable
+55
File diff suppressed because one or more lines are too long
@@ -56,8 +56,7 @@ impl Extensions {
|
||||
type AccountPublic = <Signature as Verify>::Signer;
|
||||
|
||||
/// Helper function to generate an account ID from seed
|
||||
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
|
||||
where
|
||||
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId where
|
||||
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
|
||||
{
|
||||
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
|
||||
@@ -193,3 +192,535 @@ fn shell_testnet_genesis(parachain_id: ParaId) -> shell_runtime::GenesisConfig {
|
||||
parachain_info: shell_runtime::ParachainInfoConfig { parachain_id },
|
||||
}
|
||||
}
|
||||
|
||||
use statemint_common::Balance as StatemintBalance;
|
||||
|
||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||
pub type StatemintChainSpec = sc_service::GenericChainSpec<statemint_runtime::GenesisConfig, Extensions>;
|
||||
pub type StatemineChainSpec = sc_service::GenericChainSpec<statemine_runtime::GenesisConfig, Extensions>;
|
||||
pub type WestmintChainSpec = sc_service::GenericChainSpec<westmint_runtime::GenesisConfig, Extensions>;
|
||||
|
||||
const STATEMINT_ED: StatemintBalance = statemint_runtime::constants::currency::EXISTENTIAL_DEPOSIT;
|
||||
const STATEMINE_ED: StatemintBalance = statemine_runtime::constants::currency::EXISTENTIAL_DEPOSIT;
|
||||
const WESTMINT_ED: StatemintBalance = westmint_runtime::constants::currency::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
/// Helper function to generate a crypto pair from seed
|
||||
pub fn get_pair_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
|
||||
TPublic::Pair::from_string(&format!("//{}", seed), None)
|
||||
.expect("static values are valid; qed")
|
||||
.public()
|
||||
}
|
||||
|
||||
/// Generate collator keys from seed.
|
||||
///
|
||||
/// This function's return type must always match the session keys of the chain in tuple format.
|
||||
pub fn get_collator_keys_from_seed(seed: &str) -> AuraId {
|
||||
get_pair_from_seed::<AuraId>(seed)
|
||||
}
|
||||
|
||||
/// Generate the session keys from individual elements.
|
||||
///
|
||||
/// The input must be a tuple of individual keys (a single arg for now since we have just one key).
|
||||
pub fn statemint_session_keys(keys: AuraId) -> statemint_runtime::opaque::SessionKeys {
|
||||
statemint_runtime::opaque::SessionKeys { aura: keys }
|
||||
}
|
||||
|
||||
/// Generate the session keys from individual elements.
|
||||
///
|
||||
/// The input must be a tuple of individual keys (a single arg for now since we have just one key).
|
||||
pub fn statemine_session_keys(keys: AuraId) -> statemine_runtime::opaque::SessionKeys {
|
||||
statemine_runtime::opaque::SessionKeys { aura: keys }
|
||||
}
|
||||
|
||||
/// Generate the session keys from individual elements.
|
||||
///
|
||||
/// The input must be a tuple of individual keys (a single arg for now since we have just one key).
|
||||
pub fn westmint_session_keys(keys: AuraId) -> westmint_runtime::opaque::SessionKeys {
|
||||
westmint_runtime::opaque::SessionKeys { aura: keys }
|
||||
}
|
||||
|
||||
pub fn statemint_development_config(id: ParaId) -> StatemintChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "DOT".into());
|
||||
properties.insert("tokenDecimals".into(), 10.into());
|
||||
|
||||
StatemintChainSpec::from_genesis(
|
||||
// Name
|
||||
"Statemint Development",
|
||||
// ID
|
||||
"statemint_dev",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
statemint_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
)
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "polkadot-dev".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn statemint_local_config(id: ParaId) -> StatemintChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "DOT".into());
|
||||
properties.insert("tokenDecimals".into(), 10.into());
|
||||
|
||||
StatemintChainSpec::from_genesis(
|
||||
// Name
|
||||
"Statemint Local",
|
||||
// ID
|
||||
"statemint_local",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
statemint_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice")
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob")
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "polkadot-local".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn statemint_genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> statemint_runtime::GenesisConfig {
|
||||
statemint_runtime::GenesisConfig {
|
||||
frame_system: statemint_runtime::SystemConfig {
|
||||
code: statemint_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
},
|
||||
pallet_balances: statemint_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, STATEMINT_ED * 4096))
|
||||
.collect(),
|
||||
},
|
||||
parachain_info: statemint_runtime::ParachainInfoConfig { parachain_id: id },
|
||||
pallet_collator_selection: statemint_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: STATEMINT_ED * 16,
|
||||
..Default::default()
|
||||
},
|
||||
pallet_session: statemint_runtime::SessionConfig {
|
||||
keys: invulnerables.iter().cloned().map(|(acc, aura)| (
|
||||
acc.clone(), // account id
|
||||
acc.clone(), // validator id
|
||||
statemint_session_keys(aura), // session keys
|
||||
)).collect()
|
||||
},
|
||||
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||
// of this.
|
||||
pallet_aura: Default::default(),
|
||||
cumulus_pallet_aura_ext: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn statemine_development_config(id: ParaId) -> StatemineChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "KSM".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
StatemineChainSpec::from_genesis(
|
||||
// Name
|
||||
"Statemine Development",
|
||||
// ID
|
||||
"statemine_dev",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
statemine_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
)
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "kusama-dev".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn statemine_local_config(id: ParaId) -> StatemineChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "KSM".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
StatemineChainSpec::from_genesis(
|
||||
// Name
|
||||
"Statemine Local",
|
||||
// ID
|
||||
"statemine_local",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
statemine_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice")
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob")
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "kusama-local".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn statemine_config(id: ParaId) -> StatemineChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "KSM".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
StatemineChainSpec::from_genesis(
|
||||
// Name
|
||||
"Statemine",
|
||||
// ID
|
||||
"statemine",
|
||||
ChainType::Live,
|
||||
move || {
|
||||
statemine_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
hex!("50673d59020488a4ffc9d8c6de3062a65977046e6990915617f85fef6d349730").into(),
|
||||
hex!("50673d59020488a4ffc9d8c6de3062a65977046e6990915617f85fef6d349730").unchecked_into()
|
||||
),
|
||||
(
|
||||
hex!("fe8102dbc244e7ea2babd9f53236d67403b046154370da5c3ea99def0bd0747a").into(),
|
||||
hex!("fe8102dbc244e7ea2babd9f53236d67403b046154370da5c3ea99def0bd0747a").unchecked_into()
|
||||
),
|
||||
(
|
||||
hex!("38144b5398e5d0da5ec936a3af23f5a96e782f676ab19d45f29075ee92eca76a").into(),
|
||||
hex!("38144b5398e5d0da5ec936a3af23f5a96e782f676ab19d45f29075ee92eca76a").unchecked_into()
|
||||
),
|
||||
(
|
||||
hex!("3253947640e309120ae70fa458dcacb915e2ddd78f930f52bd3679ec63fc4415").into(),
|
||||
hex!("3253947640e309120ae70fa458dcacb915e2ddd78f930f52bd3679ec63fc4415").unchecked_into()
|
||||
),
|
||||
],
|
||||
vec![],
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "kusama".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn statemine_genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> statemine_runtime::GenesisConfig {
|
||||
statemine_runtime::GenesisConfig {
|
||||
frame_system: statemine_runtime::SystemConfig {
|
||||
code: statemine_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
},
|
||||
pallet_balances: statemine_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, STATEMINE_ED * 4096))
|
||||
.collect(),
|
||||
},
|
||||
parachain_info: statemine_runtime::ParachainInfoConfig { parachain_id: id },
|
||||
pallet_collator_selection: statemine_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: STATEMINE_ED * 16,
|
||||
..Default::default()
|
||||
},
|
||||
pallet_session: statemine_runtime::SessionConfig {
|
||||
keys: invulnerables.iter().cloned().map(|(acc, aura)| (
|
||||
acc.clone(), // account id
|
||||
acc.clone(), // validator id
|
||||
statemine_session_keys(aura), // session keys
|
||||
)).collect()
|
||||
},
|
||||
pallet_aura: Default::default(),
|
||||
cumulus_pallet_aura_ext: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn westmint_development_config(id: ParaId) -> WestmintChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "WND".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
WestmintChainSpec::from_genesis(
|
||||
// Name
|
||||
"Westmint Development",
|
||||
// ID
|
||||
"westmint_dev",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
westmint_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
)
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "westend-dev".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn westmint_local_config(id: ParaId) -> WestmintChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "WND".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
WestmintChainSpec::from_genesis(
|
||||
// Name
|
||||
"Westmint Local",
|
||||
// ID
|
||||
"westmint_local",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
westmint_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice")
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob")
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "westend-local".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn westmint_config(id: ParaId) -> WestmintChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("tokenSymbol".into(), "WND".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
WestmintChainSpec::from_genesis(
|
||||
// Name
|
||||
"Westmint",
|
||||
// ID
|
||||
"westmint",
|
||||
ChainType::Live,
|
||||
move || {
|
||||
westmint_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
hex!("9cfd429fa002114f33c1d3e211501d62830c9868228eb3b4b8ae15a83de04325").into(),
|
||||
hex!("9cfd429fa002114f33c1d3e211501d62830c9868228eb3b4b8ae15a83de04325").unchecked_into()
|
||||
),
|
||||
(
|
||||
hex!("12a03fb4e7bda6c9a07ec0a11d03c24746943e054ff0bb04938970104c783876").into(),
|
||||
hex!("12a03fb4e7bda6c9a07ec0a11d03c24746943e054ff0bb04938970104c783876").unchecked_into()
|
||||
),
|
||||
(
|
||||
hex!("1256436307dfde969324e95b8c62cb9101f520a39435e6af0f7ac07b34e1931f").into(),
|
||||
hex!("1256436307dfde969324e95b8c62cb9101f520a39435e6af0f7ac07b34e1931f").unchecked_into()
|
||||
),
|
||||
(
|
||||
hex!("98102b7bca3f070f9aa19f58feed2c0a4e107d203396028ec17a47e1ed80e322").into(),
|
||||
hex!("98102b7bca3f070f9aa19f58feed2c0a4e107d203396028ec17a47e1ed80e322").unchecked_into()
|
||||
),
|
||||
],
|
||||
vec![],
|
||||
// re-use the Westend sudo key
|
||||
hex!("6648d7f3382690650c681aba1b993cd11e54deb4df21a3a18c3e2177de9f7342").into(),
|
||||
id,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
Extensions {
|
||||
relay_chain: "westend".into(),
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn westmint_genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
root_key: AccountId,
|
||||
id: ParaId,
|
||||
) -> westmint_runtime::GenesisConfig {
|
||||
westmint_runtime::GenesisConfig {
|
||||
frame_system: westmint_runtime::SystemConfig {
|
||||
code: westmint_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
},
|
||||
pallet_balances: westmint_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, WESTMINT_ED * 4096))
|
||||
.collect(),
|
||||
},
|
||||
pallet_sudo: westmint_runtime::SudoConfig { key: root_key },
|
||||
parachain_info: westmint_runtime::ParachainInfoConfig { parachain_id: id },
|
||||
pallet_collator_selection: westmint_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: WESTMINT_ED * 16,
|
||||
..Default::default()
|
||||
},
|
||||
pallet_session: westmint_runtime::SessionConfig {
|
||||
keys: invulnerables.iter().cloned().map(|(acc, aura)| (
|
||||
acc.clone(), // account id
|
||||
acc.clone(), // validator id
|
||||
westmint_session_keys(aura), // session keys
|
||||
)).collect()
|
||||
},
|
||||
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||
// of this.
|
||||
pallet_aura: Default::default(),
|
||||
cumulus_pallet_aura_ext: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,10 @@ pub enum Subcommand {
|
||||
|
||||
/// Revert the chain to a previous state.
|
||||
Revert(sc_cli::RevertCmd),
|
||||
|
||||
/// The custom benchmark subcommmand benchmarking runtime pallets.
|
||||
#[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]
|
||||
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
|
||||
}
|
||||
|
||||
/// Command for exporting the genesis state of the parachain
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
use crate::{
|
||||
chain_spec,
|
||||
cli::{Cli, RelayChainCli, Subcommand},
|
||||
service::{
|
||||
StatemineRuntimeExecutor, StatemintRuntimeExecutor, WestmintRuntimeExecutor, new_partial,
|
||||
RococoParachainRuntimeExecutor, ShellRuntimeExecutor, Block,
|
||||
},
|
||||
};
|
||||
use codec::Encode;
|
||||
use cumulus_client_service::genesis::generate_genesis_block;
|
||||
@@ -32,35 +36,83 @@ use sp_core::hexdisplay::HexDisplay;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::{io::Write, net::SocketAddr};
|
||||
|
||||
trait IdentifyChain {
|
||||
fn is_shell(&self) -> bool;
|
||||
fn is_statemint(&self) -> bool;
|
||||
fn is_statemine(&self) -> bool;
|
||||
fn is_westmint(&self) -> bool;
|
||||
}
|
||||
|
||||
impl IdentifyChain for dyn sc_service::ChainSpec {
|
||||
fn is_shell(&self) -> bool {
|
||||
self.id().starts_with("shell")
|
||||
}
|
||||
fn is_statemint(&self) -> bool {
|
||||
self.id().starts_with("statemint")
|
||||
}
|
||||
fn is_statemine(&self) -> bool {
|
||||
self.id().starts_with("statemine")
|
||||
}
|
||||
fn is_westmint(&self) -> bool {
|
||||
self.id().starts_with("westmint")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: sc_service::ChainSpec + 'static> IdentifyChain for T {
|
||||
fn is_shell(&self) -> bool {
|
||||
<dyn sc_service::ChainSpec>::is_shell(self)
|
||||
}
|
||||
fn is_statemint(&self) -> bool {
|
||||
<dyn sc_service::ChainSpec>::is_statemint(self)
|
||||
}
|
||||
fn is_statemine(&self) -> bool {
|
||||
<dyn sc_service::ChainSpec>::is_statemine(self)
|
||||
}
|
||||
fn is_westmint(&self) -> bool {
|
||||
<dyn sc_service::ChainSpec>::is_westmint(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn load_spec(
|
||||
id: &str,
|
||||
para_id: ParaId,
|
||||
) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
|
||||
match id {
|
||||
"staging" => Ok(Box::new(chain_spec::staging_test_net(para_id))),
|
||||
"tick" => Ok(Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||
Ok(match id {
|
||||
"staging" => Box::new(chain_spec::staging_test_net(para_id)),
|
||||
"tick" => Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||
&include_bytes!("../res/tick.json")[..],
|
||||
)?)),
|
||||
"trick" => Ok(Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||
)?),
|
||||
"trick" => Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||
&include_bytes!("../res/trick.json")[..],
|
||||
)?)),
|
||||
"track" => Ok(Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||
)?),
|
||||
"track" => Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||
&include_bytes!("../res/track.json")[..],
|
||||
)?)),
|
||||
"shell" => Ok(Box::new(chain_spec::get_shell_chain_spec(para_id))),
|
||||
"" => Ok(Box::new(chain_spec::get_chain_spec(para_id))),
|
||||
path => Ok({
|
||||
let chain_spec = chain_spec::ChainSpec::from_json_file(
|
||||
path.into(),
|
||||
)?;
|
||||
|
||||
if use_shell_runtime(&chain_spec) {
|
||||
)?),
|
||||
"shell" => Box::new(chain_spec::get_shell_chain_spec(para_id)),
|
||||
"statemint-dev" => Box::new(chain_spec::statemint_development_config(para_id)),
|
||||
"statemint-local" => Box::new(chain_spec::statemint_local_config(para_id)),
|
||||
"statemine-dev" => Box::new(chain_spec::statemine_development_config(para_id)),
|
||||
"statemine-local" => Box::new(chain_spec::statemine_local_config(para_id)),
|
||||
"statemine" => Box::new(chain_spec::statemine_config(para_id)),
|
||||
"westmint-dev" => Box::new(chain_spec::westmint_development_config(para_id)),
|
||||
"westmint-local" => Box::new(chain_spec::westmint_local_config(para_id)),
|
||||
"westmint" => Box::new(chain_spec::westmint_config(para_id)),
|
||||
"" => Box::new(chain_spec::get_chain_spec(para_id)),
|
||||
path => {
|
||||
let chain_spec = chain_spec::ChainSpec::from_json_file(path.into())?;
|
||||
if chain_spec.is_statemint() {
|
||||
Box::new(chain_spec::StatemintChainSpec::from_json_file(path.into())?)
|
||||
} else if chain_spec.is_statemine() {
|
||||
Box::new(chain_spec::StatemineChainSpec::from_json_file(path.into())?)
|
||||
} else if chain_spec.is_westmint() {
|
||||
Box::new(chain_spec::WestmintChainSpec::from_json_file(path.into())?)
|
||||
} else if chain_spec.is_shell() {
|
||||
Box::new(chain_spec::ShellChainSpec::from_json_file(path.into())?)
|
||||
} else {
|
||||
Box::new(chain_spec)
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl SubstrateCli for Cli {
|
||||
@@ -99,7 +151,13 @@ impl SubstrateCli for Cli {
|
||||
}
|
||||
|
||||
fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {
|
||||
if use_shell_runtime(&**chain_spec) {
|
||||
if chain_spec.is_statemint() {
|
||||
&statemint_runtime::VERSION
|
||||
} else if chain_spec.is_statemine() {
|
||||
&statemine_runtime::VERSION
|
||||
} else if chain_spec.is_westmint() {
|
||||
&westmint_runtime::VERSION
|
||||
} else if chain_spec.is_shell() {
|
||||
&shell_runtime::VERSION
|
||||
} else {
|
||||
&rococo_parachain_runtime::VERSION
|
||||
@@ -157,16 +215,37 @@ fn extract_genesis_wasm(chain_spec: &Box<dyn sc_service::ChainSpec>) -> Result<V
|
||||
.ok_or_else(|| "Could not find wasm file in genesis state!".into())
|
||||
}
|
||||
|
||||
fn use_shell_runtime(chain_spec: &dyn ChainSpec) -> bool {
|
||||
chain_spec.id().starts_with("shell")
|
||||
}
|
||||
|
||||
use crate::service::{new_partial, RococoParachainRuntimeExecutor, ShellRuntimeExecutor};
|
||||
|
||||
macro_rules! construct_async_run {
|
||||
(|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{
|
||||
let runner = $cli.create_runner($cmd)?;
|
||||
if use_shell_runtime(&*runner.config().chain_spec) {
|
||||
if runner.config().chain_spec.is_westmint() {
|
||||
runner.async_run(|$config| {
|
||||
let $components = new_partial::<westmint_runtime::RuntimeApi, WestmintRuntimeExecutor, _>(
|
||||
&$config,
|
||||
crate::service::statemint_build_import_queue,
|
||||
)?;
|
||||
let task_manager = $components.task_manager;
|
||||
{ $( $code )* }.map(|v| (v, task_manager))
|
||||
})
|
||||
} else if runner.config().chain_spec.is_statemine() {
|
||||
runner.async_run(|$config| {
|
||||
let $components = new_partial::<statemine_runtime::RuntimeApi, StatemineRuntimeExecutor, _>(
|
||||
&$config,
|
||||
crate::service::statemint_build_import_queue,
|
||||
)?;
|
||||
let task_manager = $components.task_manager;
|
||||
{ $( $code )* }.map(|v| (v, task_manager))
|
||||
})
|
||||
} else if runner.config().chain_spec.is_statemint() {
|
||||
runner.async_run(|$config| {
|
||||
let $components = new_partial::<statemint_runtime::RuntimeApi, StatemintRuntimeExecutor, _>(
|
||||
&$config,
|
||||
crate::service::statemint_build_import_queue,
|
||||
)?;
|
||||
let task_manager = $components.task_manager;
|
||||
{ $( $code )* }.map(|v| (v, task_manager))
|
||||
})
|
||||
} else if runner.config().chain_spec.is_shell() {
|
||||
runner.async_run(|$config| {
|
||||
let $components = new_partial::<shell_runtime::RuntimeApi, ShellRuntimeExecutor, _>(
|
||||
&$config,
|
||||
@@ -290,9 +369,26 @@ pub fn run() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Some(Subcommand::Benchmark(cmd)) => {
|
||||
if cfg!(feature = "runtime-benchmarks") {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
if runner.config().chain_spec.is_statemine() {
|
||||
runner.sync_run(|config| cmd.run::<Block, StatemineRuntimeExecutor>(config))
|
||||
} else if runner.config().chain_spec.is_westmint() {
|
||||
runner.sync_run(|config| cmd.run::<Block, WestmintRuntimeExecutor>(config))
|
||||
} else if runner.config().chain_spec.is_statemint() {
|
||||
runner.sync_run(|config| cmd.run::<Block, StatemintRuntimeExecutor>(config))
|
||||
} else {
|
||||
Err("Chain doesn't support benchmarking".into())
|
||||
}
|
||||
} else {
|
||||
Err("Benchmarking wasn't enabled when building the node. \
|
||||
You can enable it with `--features runtime-benchmarks`."
|
||||
.into())
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let runner = cli.create_runner(&cli.run.normalize())?;
|
||||
let use_shell = use_shell_runtime(&*runner.config().chain_spec);
|
||||
|
||||
runner.run_node_until_exit(|config| async move {
|
||||
// TODO
|
||||
@@ -334,7 +430,37 @@ pub fn run() -> Result<()> {
|
||||
}
|
||||
);
|
||||
|
||||
if use_shell {
|
||||
if config.chain_spec.is_statemint() {
|
||||
crate::service::start_statemint_node::<statemint_runtime::RuntimeApi, StatemintRuntimeExecutor>(
|
||||
config,
|
||||
key,
|
||||
polkadot_config,
|
||||
id,
|
||||
)
|
||||
.await
|
||||
.map(|r| r.0)
|
||||
.map_err(Into::into)
|
||||
} else if config.chain_spec.is_statemine() {
|
||||
crate::service::start_statemint_node::<statemine_runtime::RuntimeApi, StatemineRuntimeExecutor>(
|
||||
config,
|
||||
key,
|
||||
polkadot_config,
|
||||
id,
|
||||
)
|
||||
.await
|
||||
.map(|r| r.0)
|
||||
.map_err(Into::into)
|
||||
} else if config.chain_spec.is_westmint() {
|
||||
crate::service::start_statemint_node::<westmint_runtime::RuntimeApi, WestmintRuntimeExecutor>(
|
||||
config,
|
||||
key,
|
||||
polkadot_config,
|
||||
id,
|
||||
)
|
||||
.await
|
||||
.map(|r| r.0)
|
||||
.map_err(Into::into)
|
||||
} else if config.chain_spec.is_shell() {
|
||||
crate::service::start_shell_node(config, key, polkadot_config, id)
|
||||
.await
|
||||
.map(|r| r.0)
|
||||
|
||||
@@ -17,12 +17,16 @@
|
||||
use cumulus_client_consensus_aura::{
|
||||
build_aura_consensus, BuildAuraConsensusParams, SlotProportion,
|
||||
};
|
||||
use cumulus_client_consensus_common::ParachainConsensus;
|
||||
use cumulus_client_consensus_common::{
|
||||
ParachainConsensus, ParachainCandidate, ParachainBlockImport,
|
||||
};
|
||||
use cumulus_client_network::build_block_announce_validator;
|
||||
use cumulus_client_service::{
|
||||
prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,
|
||||
};
|
||||
use cumulus_primitives_core::ParaId;
|
||||
use cumulus_primitives_core::{
|
||||
ParaId, relay_chain::v1::{Hash as PHash, PersistedValidationData},
|
||||
};
|
||||
use polkadot_primitives::v1::CollatorPair;
|
||||
|
||||
use sc_client_api::ExecutorProvider;
|
||||
@@ -30,12 +34,18 @@ use sc_executor::native_executor_instance;
|
||||
use sc_network::NetworkService;
|
||||
use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager};
|
||||
use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};
|
||||
use sp_api::ConstructRuntimeApi;
|
||||
use sp_consensus::SlotData;
|
||||
use sp_api::{ConstructRuntimeApi, ApiExt};
|
||||
use sp_consensus::{
|
||||
BlockImportParams, BlockOrigin, SlotData,
|
||||
import_queue::{BasicQueue, CacheKeyId, Verifier as VerifierT},
|
||||
};
|
||||
use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi};
|
||||
use sp_keystore::SyncCryptoStorePtr;
|
||||
use sp_runtime::traits::BlakeTwo256;
|
||||
use sp_runtime::{traits::{BlakeTwo256, Header as HeaderT}, generic::BlockId};
|
||||
use std::sync::Arc;
|
||||
use substrate_prometheus_endpoint::Registry;
|
||||
use futures::lock::Mutex;
|
||||
use cumulus_client_consensus_relay_chain::Verifier as RelayChainVerifier;
|
||||
|
||||
pub use sc_executor::NativeExecutor;
|
||||
|
||||
@@ -58,6 +68,30 @@ native_executor_instance!(
|
||||
shell_runtime::native_version,
|
||||
);
|
||||
|
||||
// Native Statemint executor instance.
|
||||
native_executor_instance!(
|
||||
pub StatemintRuntimeExecutor,
|
||||
statemint_runtime::api::dispatch,
|
||||
statemint_runtime::native_version,
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
// Native Statemine executor instance.
|
||||
native_executor_instance!(
|
||||
pub StatemineRuntimeExecutor,
|
||||
statemine_runtime::api::dispatch,
|
||||
statemine_runtime::native_version,
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
// Native Westmint executor instance.
|
||||
native_executor_instance!(
|
||||
pub WestmintRuntimeExecutor,
|
||||
westmint_runtime::api::dispatch,
|
||||
westmint_runtime::native_version,
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
/// Starts a `ServiceBuilder` for a full service.
|
||||
///
|
||||
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
||||
@@ -326,7 +360,9 @@ where
|
||||
|
||||
/// Build the import queue for the rococo parachain runtime.
|
||||
pub fn rococo_parachain_build_import_queue(
|
||||
client: Arc<TFullClient<Block, rococo_parachain_runtime::RuntimeApi, RococoParachainRuntimeExecutor>>,
|
||||
client: Arc<
|
||||
TFullClient<Block, rococo_parachain_runtime::RuntimeApi, RococoParachainRuntimeExecutor>,
|
||||
>,
|
||||
config: &Configuration,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
task_manager: &TaskManager,
|
||||
@@ -339,33 +375,29 @@ pub fn rococo_parachain_build_import_queue(
|
||||
> {
|
||||
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
|
||||
|
||||
cumulus_client_consensus_aura::import_queue::<
|
||||
sp_consensus_aura::sr25519::AuthorityPair,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
>(cumulus_client_consensus_aura::ImportQueueParams {
|
||||
block_import: client.clone(),
|
||||
client: client.clone(),
|
||||
create_inherent_data_providers: move |_, _| async move {
|
||||
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
cumulus_client_consensus_aura::import_queue::<sp_consensus_aura::sr25519::AuthorityPair, _, _, _, _, _, _>(
|
||||
cumulus_client_consensus_aura::ImportQueueParams {
|
||||
block_import: client.clone(),
|
||||
client: client.clone(),
|
||||
create_inherent_data_providers: move |_, _| async move {
|
||||
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
*time,
|
||||
slot_duration.slot_duration(),
|
||||
);
|
||||
let slot =
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
*time,
|
||||
slot_duration.slot_duration(),
|
||||
);
|
||||
|
||||
Ok((time, slot))
|
||||
Ok((time, slot))
|
||||
},
|
||||
registry: config.prometheus_registry().clone(),
|
||||
can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(
|
||||
client.executor().clone(),
|
||||
),
|
||||
spawner: &task_manager.spawn_essential_handle(),
|
||||
telemetry,
|
||||
},
|
||||
registry: config.prometheus_registry().clone(),
|
||||
can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
|
||||
spawner: &task_manager.spawn_essential_handle(),
|
||||
telemetry,
|
||||
})
|
||||
)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
@@ -375,9 +407,10 @@ pub async fn start_rococo_parachain_node(
|
||||
collator_key: CollatorPair,
|
||||
polkadot_config: Configuration,
|
||||
id: ParaId,
|
||||
) -> sc_service::error::Result<
|
||||
(TaskManager, Arc<TFullClient<Block, rococo_parachain_runtime::RuntimeApi, RococoParachainRuntimeExecutor>>)
|
||||
> {
|
||||
) -> sc_service::error::Result<(
|
||||
TaskManager,
|
||||
Arc<TFullClient<Block, rococo_parachain_runtime::RuntimeApi, RococoParachainRuntimeExecutor>>,
|
||||
)> {
|
||||
start_node_impl::<rococo_parachain_runtime::RuntimeApi, RococoParachainRuntimeExecutor, _, _, _>(
|
||||
parachain_config,
|
||||
collator_key,
|
||||
@@ -486,15 +519,16 @@ pub fn shell_build_import_queue(
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Start a rococo-shell parachain node.
|
||||
/// Start a polkadot-shell parachain node.
|
||||
pub async fn start_shell_node(
|
||||
parachain_config: Configuration,
|
||||
collator_key: CollatorPair,
|
||||
polkadot_config: Configuration,
|
||||
id: ParaId,
|
||||
) -> sc_service::error::Result<
|
||||
(TaskManager, Arc<TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>>)
|
||||
> {
|
||||
) -> sc_service::error::Result<(
|
||||
TaskManager,
|
||||
Arc<TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>>,
|
||||
)> {
|
||||
start_node_impl::<shell_runtime::RuntimeApi, ShellRuntimeExecutor, _, _, _>(
|
||||
parachain_config,
|
||||
collator_key,
|
||||
@@ -557,3 +591,379 @@ pub async fn start_shell_node(
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
enum BuildOnAccess<R> {
|
||||
Uninitialized(Option<Box<dyn FnOnce() -> R + Send + Sync>>),
|
||||
Initialized(R),
|
||||
}
|
||||
|
||||
impl<R> BuildOnAccess<R> {
|
||||
fn get_mut(&mut self) -> &mut R {
|
||||
loop {
|
||||
match self {
|
||||
Self::Uninitialized(f) => {
|
||||
*self = Self::Initialized((f.take().unwrap())());
|
||||
}
|
||||
Self::Initialized(ref mut r) => return r,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Special [`ParachainConsensus`] implementation that waits for the upgrade from
|
||||
/// shell to a parachain runtime that implements Aura.
|
||||
struct WaitForAuraConsensus<Client> {
|
||||
client: Arc<Client>,
|
||||
aura_consensus: Arc<Mutex<BuildOnAccess<Box<dyn ParachainConsensus<Block>>>>>,
|
||||
relay_chain_consensus: Arc<Mutex<Box<dyn ParachainConsensus<Block>>>>,
|
||||
}
|
||||
|
||||
impl<Client> Clone for WaitForAuraConsensus<Client> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
client: self.client.clone(),
|
||||
aura_consensus: self.aura_consensus.clone(),
|
||||
relay_chain_consensus: self.relay_chain_consensus.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<Client> ParachainConsensus<Block> for WaitForAuraConsensus<Client>
|
||||
where
|
||||
Client: sp_api::ProvideRuntimeApi<Block> + Send + Sync,
|
||||
Client::Api: AuraApi<Block, AuraId>,
|
||||
{
|
||||
async fn produce_candidate(
|
||||
&mut self,
|
||||
parent: &Header,
|
||||
relay_parent: PHash,
|
||||
validation_data: &PersistedValidationData,
|
||||
) -> Option<ParachainCandidate<Block>> {
|
||||
let block_id = BlockId::hash(parent.hash());
|
||||
if self
|
||||
.client
|
||||
.runtime_api()
|
||||
.has_api::<dyn AuraApi<Block, AuraId>>(&block_id)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
self.aura_consensus
|
||||
.lock()
|
||||
.await
|
||||
.get_mut()
|
||||
.produce_candidate(parent, relay_parent, validation_data)
|
||||
.await
|
||||
} else {
|
||||
self.relay_chain_consensus
|
||||
.lock()
|
||||
.await
|
||||
.produce_candidate(parent, relay_parent, validation_data)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Verifier<Client> {
|
||||
client: Arc<Client>,
|
||||
aura_verifier: BuildOnAccess<Box<dyn VerifierT<Block>>>,
|
||||
relay_chain_verifier: Box<dyn VerifierT<Block>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<Client> VerifierT<Block> for Verifier<Client>
|
||||
where
|
||||
Client: sp_api::ProvideRuntimeApi<Block> + Send + Sync,
|
||||
Client::Api: AuraApi<Block, AuraId>,
|
||||
{
|
||||
async fn verify(
|
||||
&mut self,
|
||||
origin: BlockOrigin,
|
||||
header: Header,
|
||||
justifications: Option<sp_runtime::Justifications>,
|
||||
body: Option<Vec<<Block as sp_runtime::traits::Block>::Extrinsic>>,
|
||||
) -> Result<
|
||||
(
|
||||
BlockImportParams<Block, ()>,
|
||||
Option<Vec<(CacheKeyId, Vec<u8>)>>,
|
||||
),
|
||||
String,
|
||||
> {
|
||||
let block_id = BlockId::hash(*header.parent_hash());
|
||||
|
||||
if self
|
||||
.client
|
||||
.runtime_api()
|
||||
.has_api::<dyn AuraApi<Block, AuraId>>(&block_id)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
self.aura_verifier
|
||||
.get_mut()
|
||||
.verify(origin, header, justifications, body)
|
||||
.await
|
||||
} else {
|
||||
self.relay_chain_verifier
|
||||
.verify(origin, header, justifications, body)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the import queue for the statemint/statemine/westmine runtime.
|
||||
pub fn statemint_build_import_queue<RuntimeApi, Executor>(
|
||||
client: Arc<TFullClient<Block, RuntimeApi, Executor>>,
|
||||
config: &Configuration,
|
||||
telemetry_handle: Option<TelemetryHandle>,
|
||||
task_manager: &TaskManager,
|
||||
) -> Result<
|
||||
sp_consensus::DefaultImportQueue<Block, TFullClient<Block, RuntimeApi, Executor>>,
|
||||
sc_service::Error,
|
||||
>
|
||||
where
|
||||
RuntimeApi: ConstructRuntimeApi<Block, TFullClient<Block, RuntimeApi, Executor>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ sp_api::ApiExt<
|
||||
Block,
|
||||
StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>,
|
||||
> + sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ sp_consensus_aura::AuraApi<Block, AuraId>,
|
||||
sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
|
||||
Executor: sc_executor::NativeExecutionDispatch + 'static,
|
||||
{
|
||||
let client2 = client.clone();
|
||||
|
||||
let aura_verifier = move || {
|
||||
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client2).unwrap();
|
||||
|
||||
Box::new(cumulus_client_consensus_aura::build_verifier::<
|
||||
sp_consensus_aura::sr25519::AuthorityPair,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
>(cumulus_client_consensus_aura::BuildVerifierParams {
|
||||
client: client2.clone(),
|
||||
create_inherent_data_providers: move |_, _| async move {
|
||||
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
*time,
|
||||
slot_duration.slot_duration(),
|
||||
);
|
||||
|
||||
Ok((time, slot))
|
||||
},
|
||||
can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(
|
||||
client2.executor().clone(),
|
||||
),
|
||||
telemetry: telemetry_handle,
|
||||
})) as Box<_>
|
||||
};
|
||||
|
||||
let relay_chain_verifier = Box::new(RelayChainVerifier::new(client.clone(), |_, _| async {
|
||||
Ok(())
|
||||
})) as Box<_>;
|
||||
|
||||
let verifier = Verifier {
|
||||
client: client.clone(),
|
||||
relay_chain_verifier,
|
||||
aura_verifier: BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier))),
|
||||
};
|
||||
|
||||
let registry = config.prometheus_registry().clone();
|
||||
let spawner = task_manager.spawn_essential_handle();
|
||||
|
||||
Ok(BasicQueue::new(
|
||||
verifier,
|
||||
Box::new(ParachainBlockImport::new(client.clone())),
|
||||
None,
|
||||
&spawner,
|
||||
registry,
|
||||
))
|
||||
}
|
||||
|
||||
/// Start a statemint/statemine/westmint parachain node.
|
||||
pub async fn start_statemint_node<RuntimeApi, Executor>(
|
||||
parachain_config: Configuration,
|
||||
collator_key: CollatorPair,
|
||||
polkadot_config: Configuration,
|
||||
id: ParaId,
|
||||
) -> sc_service::error::Result<(
|
||||
TaskManager,
|
||||
Arc<TFullClient<Block, RuntimeApi, Executor>>,
|
||||
)>
|
||||
where
|
||||
RuntimeApi: ConstructRuntimeApi<Block, TFullClient<Block, RuntimeApi, Executor>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ sp_api::ApiExt<
|
||||
Block,
|
||||
StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>,
|
||||
> + sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ cumulus_primitives_core::CollectCollationInfo<Block>
|
||||
+ sp_consensus_aura::AuraApi<Block, AuraId>,
|
||||
sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
|
||||
Executor: sc_executor::NativeExecutionDispatch + 'static,
|
||||
{
|
||||
start_node_impl::<RuntimeApi, Executor, _, _, _>(
|
||||
parachain_config,
|
||||
collator_key,
|
||||
polkadot_config,
|
||||
id,
|
||||
|_| Default::default(),
|
||||
statemint_build_import_queue,
|
||||
|client,
|
||||
prometheus_registry,
|
||||
telemetry,
|
||||
task_manager,
|
||||
relay_chain_node,
|
||||
transaction_pool,
|
||||
sync_oracle,
|
||||
keystore,
|
||||
force_authoring| {
|
||||
let client2 = client.clone();
|
||||
let relay_chain_backend = relay_chain_node.backend.clone();
|
||||
let relay_chain_client = relay_chain_node.client.clone();
|
||||
let spawn_handle = task_manager.spawn_handle();
|
||||
let transaction_pool2 = transaction_pool.clone();
|
||||
let telemetry2 = telemetry.clone();
|
||||
let prometheus_registry2 = prometheus_registry.map(|r| (*r).clone());
|
||||
|
||||
let aura_consensus = BuildOnAccess::Uninitialized(Some(
|
||||
Box::new(move || {
|
||||
let slot_duration =
|
||||
cumulus_client_consensus_aura::slot_duration(&*client2).unwrap();
|
||||
|
||||
let proposer_factory =
|
||||
sc_basic_authorship::ProposerFactory::with_proof_recording(
|
||||
spawn_handle,
|
||||
client2.clone(),
|
||||
transaction_pool2,
|
||||
prometheus_registry2.as_ref(),
|
||||
telemetry2.clone(),
|
||||
);
|
||||
|
||||
let relay_chain_backend2 = relay_chain_backend.clone();
|
||||
let relay_chain_client2 = relay_chain_client.clone();
|
||||
|
||||
build_aura_consensus::<
|
||||
sp_consensus_aura::sr25519::AuthorityPair,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
>(BuildAuraConsensusParams {
|
||||
proposer_factory,
|
||||
create_inherent_data_providers:
|
||||
move |_, (relay_parent, validation_data)| {
|
||||
let parachain_inherent =
|
||||
cumulus_primitives_parachain_inherent::ParachainInherentData::create_at_with_client(
|
||||
relay_parent,
|
||||
&relay_chain_client,
|
||||
&*relay_chain_backend,
|
||||
&validation_data,
|
||||
id,
|
||||
);
|
||||
async move {
|
||||
let time =
|
||||
sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
*time,
|
||||
slot_duration.slot_duration(),
|
||||
);
|
||||
|
||||
let parachain_inherent =
|
||||
parachain_inherent.ok_or_else(|| {
|
||||
Box::<dyn std::error::Error + Send + Sync>::from(
|
||||
"Failed to create parachain inherent",
|
||||
)
|
||||
})?;
|
||||
Ok((time, slot, parachain_inherent))
|
||||
}
|
||||
},
|
||||
block_import: client2.clone(),
|
||||
relay_chain_client: relay_chain_client2,
|
||||
relay_chain_backend: relay_chain_backend2,
|
||||
para_client: client2.clone(),
|
||||
backoff_authoring_blocks: Option::<()>::None,
|
||||
sync_oracle,
|
||||
keystore,
|
||||
force_authoring,
|
||||
slot_duration,
|
||||
// We got around 500ms for proposing
|
||||
block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),
|
||||
telemetry: telemetry2,
|
||||
})
|
||||
}),
|
||||
));
|
||||
|
||||
let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(
|
||||
task_manager.spawn_handle(),
|
||||
client.clone(),
|
||||
transaction_pool,
|
||||
prometheus_registry.clone(),
|
||||
telemetry.clone(),
|
||||
);
|
||||
|
||||
let relay_chain_backend = relay_chain_node.backend.clone();
|
||||
let relay_chain_client = relay_chain_node.client.clone();
|
||||
|
||||
let relay_chain_consensus =
|
||||
cumulus_client_consensus_relay_chain::build_relay_chain_consensus(
|
||||
cumulus_client_consensus_relay_chain::BuildRelayChainConsensusParams {
|
||||
para_id: id,
|
||||
proposer_factory,
|
||||
block_import: client.clone(),
|
||||
relay_chain_client: relay_chain_node.client.clone(),
|
||||
relay_chain_backend: relay_chain_node.backend.clone(),
|
||||
create_inherent_data_providers:
|
||||
move |_, (relay_parent, validation_data)| {
|
||||
let parachain_inherent =
|
||||
cumulus_primitives_parachain_inherent::ParachainInherentData::create_at_with_client(
|
||||
relay_parent,
|
||||
&relay_chain_client,
|
||||
&*relay_chain_backend,
|
||||
&validation_data,
|
||||
id,
|
||||
);
|
||||
async move {
|
||||
let parachain_inherent =
|
||||
parachain_inherent.ok_or_else(|| {
|
||||
Box::<dyn std::error::Error + Send + Sync>::from(
|
||||
"Failed to create parachain inherent",
|
||||
)
|
||||
})?;
|
||||
Ok(parachain_inherent)
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
let parachain_consensus = Box::new(WaitForAuraConsensus {
|
||||
client: client.clone(),
|
||||
aura_consensus: Arc::new(Mutex::new(aura_consensus)),
|
||||
relay_chain_consensus: Arc::new(Mutex::new(relay_chain_consensus)),
|
||||
});
|
||||
|
||||
Ok(parachain_consensus)
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
[package]
|
||||
name = 'statemine-runtime'
|
||||
version = '1.0.0'
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = '2018'
|
||||
description = "Kusama variant of Statemint parachain runtime"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
|
||||
log = { version = "0.4.14", default-features = false }
|
||||
parachain-info = { path = "../pallets/parachain-info", default-features = false }
|
||||
smallvec = "1.6.1"
|
||||
hex-literal = { version = '0.3.1', optional = true }
|
||||
|
||||
# Substrate dependencies
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
frame-benchmarking = { git = "https://github.com/paritytech/substrate", optional = true, default-features = false, branch = "master" }
|
||||
frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", optional = true, default-features = false, branch = "master" }
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-assets = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-authorship = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-multisig = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-proxy = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-utility = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
node-primitives = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
max-encoded-len = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
# Cumulus dependencies
|
||||
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
|
||||
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
|
||||
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
||||
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
|
||||
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
|
||||
cumulus-pallet-xcm = { path = "../../pallets/xcm", default-features = false }
|
||||
cumulus-ping = { path = "../pallets/ping", default-features = false }
|
||||
pallet-collator-selection = { path = "../../pallets/collator-selection", default-features = false }
|
||||
statemint-common = { path = "../statemint-common", default-features = false }
|
||||
|
||||
# Polkadot dependencies
|
||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.3.1"
|
||||
hex = "0.4.3"
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
runtime-benchmarks = [
|
||||
'hex-literal',
|
||||
'sp-runtime/runtime-benchmarks',
|
||||
'xcm-builder/runtime-benchmarks',
|
||||
'frame-benchmarking',
|
||||
'frame-system-benchmarking',
|
||||
'frame-support/runtime-benchmarks',
|
||||
'frame-system/runtime-benchmarks',
|
||||
'pallet-assets/runtime-benchmarks',
|
||||
'pallet-balances/runtime-benchmarks',
|
||||
'pallet-multisig/runtime-benchmarks',
|
||||
'pallet-proxy/runtime-benchmarks',
|
||||
'pallet-utility/runtime-benchmarks',
|
||||
'pallet-timestamp/runtime-benchmarks',
|
||||
'pallet-xcm/runtime-benchmarks',
|
||||
'pallet-collator-selection/runtime-benchmarks',
|
||||
]
|
||||
std = [
|
||||
"codec/std",
|
||||
"serde",
|
||||
"log/std",
|
||||
"sp-api/std",
|
||||
"sp-std/std",
|
||||
"sp-io/std",
|
||||
"sp-core/std",
|
||||
"sp-runtime/std",
|
||||
"sp-version/std",
|
||||
"sp-offchain/std",
|
||||
"sp-session/std",
|
||||
"sp-block-builder/std",
|
||||
"sp-transaction-pool/std",
|
||||
"sp-inherents/std",
|
||||
"frame-support/std",
|
||||
"frame-executive/std",
|
||||
"frame-system/std",
|
||||
"frame-system-rpc-runtime-api/std",
|
||||
"pallet-assets/std",
|
||||
"pallet-authorship/std",
|
||||
"pallet-aura/std",
|
||||
"pallet-balances/std",
|
||||
"pallet-multisig/std",
|
||||
"pallet-proxy/std",
|
||||
"pallet-randomness-collective-flip/std",
|
||||
"pallet-session/std",
|
||||
"pallet-sudo/std",
|
||||
"pallet-timestamp/std",
|
||||
"pallet-transaction-payment/std",
|
||||
"pallet-transaction-payment-rpc-runtime-api/std",
|
||||
"pallet-utility/std",
|
||||
"parachain-info/std",
|
||||
"cumulus-pallet-aura-ext/std",
|
||||
"pallet-collator-selection/std",
|
||||
"cumulus-pallet-dmp-queue/std",
|
||||
"cumulus-pallet-parachain-system/std",
|
||||
"cumulus-pallet-xcmp-queue/std",
|
||||
"cumulus-pallet-xcm/std",
|
||||
"cumulus-primitives-core/std",
|
||||
"cumulus-primitives-utility/std",
|
||||
"cumulus-ping/std",
|
||||
"xcm/std",
|
||||
"xcm-builder/std",
|
||||
"xcm-executor/std",
|
||||
"sp-consensus-aura/std",
|
||||
"node-primitives/std",
|
||||
"statemint-common/std",
|
||||
]
|
||||
@@ -0,0 +1,9 @@
|
||||
use substrate_wasm_builder::WasmBuilder;
|
||||
|
||||
fn main() {
|
||||
WasmBuilder::new()
|
||||
.with_current_project()
|
||||
.export_heap_base()
|
||||
.import_memory()
|
||||
.build()
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub mod currency {
|
||||
use node_primitives::Balance;
|
||||
|
||||
/// The existential deposit. Set to 1/10 of its parent Relay Chain (v9020).
|
||||
pub const EXISTENTIAL_DEPOSIT: Balance = CENTS / 10;
|
||||
|
||||
pub const UNITS: Balance = 1_000_000_000_000;
|
||||
pub const CENTS: Balance = UNITS / 30_000;
|
||||
pub const GRAND: Balance = CENTS * 100_000;
|
||||
pub const MILLICENTS: Balance = CENTS / 1_000;
|
||||
|
||||
pub const fn deposit(items: u32, bytes: u32) -> Balance {
|
||||
// map to 1/10 of what the kusama relay chain charges (v9020)
|
||||
(items as Balance * 2_000 * CENTS + (bytes as Balance) * 100 * MILLICENTS) / 10
|
||||
}
|
||||
}
|
||||
|
||||
/// Fee-related.
|
||||
pub mod fee {
|
||||
use node_primitives::Balance;
|
||||
pub use sp_runtime::Perbill;
|
||||
use frame_support::weights::{
|
||||
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
|
||||
WeightToFeePolynomial,
|
||||
};
|
||||
use smallvec::smallvec;
|
||||
|
||||
/// The block saturation level. Fees will be updates based on this value.
|
||||
pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
|
||||
|
||||
/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
|
||||
/// node's balance type.
|
||||
///
|
||||
/// This should typically create a mapping between the following ranges:
|
||||
/// - [0, MAXIMUM_BLOCK_WEIGHT]
|
||||
/// - [Balance::min, Balance::max]
|
||||
///
|
||||
/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
|
||||
/// - Setting it to `0` will essentially disable the weight fee.
|
||||
/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
|
||||
pub struct WeightToFee;
|
||||
impl WeightToFeePolynomial for WeightToFee {
|
||||
type Balance = Balance;
|
||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||
// in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||
// in Statemine, we map to 1/10 of that, or 1/100 CENT
|
||||
let p = super::currency::CENTS;
|
||||
let q = 100 * Balance::from(ExtrinsicBaseWeight::get());
|
||||
smallvec![WeightToFeeCoefficient {
|
||||
degree: 1,
|
||||
negative: false,
|
||||
coeff_frac: Perbill::from_rational(p % q, q),
|
||||
coeff_integer: p / q,
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,837 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Statemine runtime.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
// Make the WASM binary available.
|
||||
#[cfg(feature = "std")]
|
||||
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
|
||||
pub mod constants;
|
||||
mod weights;
|
||||
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||
use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT};
|
||||
use sp_runtime::{
|
||||
create_runtime_str, generic, impl_opaque_keys,
|
||||
transaction_validity::{TransactionSource, TransactionValidity},
|
||||
ApplyExtrinsicResult,
|
||||
};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_version::NativeVersion;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
use frame_system::{
|
||||
EnsureOneOf, EnsureRoot, limits::{BlockLength, BlockWeights},
|
||||
};
|
||||
use statemint_common::{
|
||||
BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId, Header,
|
||||
NORMAL_DISPATCH_RATIO, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, SLOT_DURATION, HOURS,
|
||||
};
|
||||
pub use statemint_common as common;
|
||||
use statemint_common::impls::DealWithFees;
|
||||
use codec::{Decode, Encode};
|
||||
use constants::{currency::*, fee::WeightToFee};
|
||||
use frame_support::{
|
||||
construct_runtime, parameter_types, match_type,
|
||||
traits::{InstanceFilter, All, Filter, MaxEncodedLen},
|
||||
weights::{
|
||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
|
||||
DispatchClass, IdentityFee, Weight,
|
||||
},
|
||||
RuntimeDebug, PalletId,
|
||||
};
|
||||
use sp_runtime::Perbill;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
|
||||
// Polkadot imports
|
||||
use polkadot_parachain::primitives::Sibling;
|
||||
use polkadot_runtime_common::{
|
||||
BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate,
|
||||
};
|
||||
use xcm::v0::{MultiAsset, Junction, MultiLocation, NetworkId, Xcm, BodyId};
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
|
||||
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
|
||||
SovereignSignedViaLocation, EnsureXcmOrigin,
|
||||
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
|
||||
AllowUnpaidExecutionFrom, ParentAsSuperuser, SignedToAccountId32, UsingComponents,
|
||||
};
|
||||
use xcm_executor::{Config, XcmExecutor};
|
||||
use pallet_xcm::{XcmPassthrough, EnsureXcm, IsMajorityOfBody};
|
||||
|
||||
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
|
||||
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
|
||||
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
|
||||
/// to even the core data structures.
|
||||
pub mod opaque {
|
||||
use super::*;
|
||||
pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
|
||||
/// Opaque block header type.
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
||||
/// Opaque block type.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// Opaque block identifier type.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
impl_opaque_keys! {
|
||||
pub struct SessionKeys {
|
||||
pub aura: Aura,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[sp_version::runtime_version]
|
||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("statemine"),
|
||||
impl_name: create_runtime_str!("statemine"),
|
||||
authoring_version: 1,
|
||||
spec_version: 1,
|
||||
impl_version: 1,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
};
|
||||
|
||||
/// The version information used to identify this runtime when compiled natively.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn native_version() -> NativeVersion {
|
||||
NativeVersion {
|
||||
runtime_version: VERSION,
|
||||
can_author_with: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
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 = 2;
|
||||
}
|
||||
|
||||
// Don't allow permission-less asset creation.
|
||||
pub struct BaseFilter;
|
||||
impl Filter<Call> for BaseFilter {
|
||||
fn filter(c: &Call) -> bool {
|
||||
!matches!(c,
|
||||
Call::Assets(pallet_assets::Call::create(..))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Configure FRAME pallets to include in runtime.
|
||||
impl frame_system::Config for Runtime {
|
||||
type BaseCallFilter = BaseFilter;
|
||||
type BlockWeights = RuntimeBlockWeights;
|
||||
type BlockLength = RuntimeBlockLength;
|
||||
type AccountId = AccountId;
|
||||
type Call = Call;
|
||||
type Lookup = AccountIdLookup<AccountId, ()>;
|
||||
type Index = Index;
|
||||
type BlockNumber = BlockNumber;
|
||||
type Hash = Hash;
|
||||
type Hashing = BlakeTwo256;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type Origin = Origin;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type DbWeight = RocksDbWeight;
|
||||
type Version = Version;
|
||||
type PalletInfo = PalletInfo;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type AccountData = pallet_balances::AccountData<Balance>;
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
||||
}
|
||||
|
||||
impl pallet_timestamp::Config for Runtime {
|
||||
/// A timestamp: milliseconds since the unix epoch.
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = ();
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const UncleGenerations: u32 = 0;
|
||||
}
|
||||
|
||||
impl pallet_authorship::Config for Runtime {
|
||||
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
|
||||
type UncleGenerations = UncleGenerations;
|
||||
type FilterUncle = ();
|
||||
type EventHandler = (CollatorSelection,);
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||
pub const MaxLocks: u32 = 50;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
type MaxLocks = MaxLocks;
|
||||
/// The type for recording an account's balance.
|
||||
type Balance = Balance;
|
||||
/// The ubiquitous event type.
|
||||
type Event = Event;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
/// Relay Chain `TransactionByteFee` / 10
|
||||
pub const TransactionByteFee: Balance = 1 * MILLICENTS;
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction =
|
||||
pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees<Runtime>>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = WeightToFee;
|
||||
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const AssetDeposit: Balance = UNITS; // 1 UNIT deposit to create asset
|
||||
pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||
pub const StringLimit: u32 = 50;
|
||||
/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
|
||||
// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
|
||||
pub const MetadataDepositBase: Balance = deposit(1, 68);
|
||||
pub const MetadataDepositPerByte: Balance = deposit(0, 1);
|
||||
pub const ExecutiveBody: BodyId = BodyId::Executive;
|
||||
}
|
||||
|
||||
/// We allow root and the Relay Chain council to execute privileged asset operations.
|
||||
pub type AssetsForceOrigin = EnsureOneOf<
|
||||
AccountId,
|
||||
EnsureRoot<AccountId>,
|
||||
EnsureXcm<IsMajorityOfBody<KsmLocation, ExecutiveBody>>,
|
||||
>;
|
||||
|
||||
impl pallet_assets::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Balance = Balance;
|
||||
type AssetId = u32;
|
||||
type Currency = Balances;
|
||||
type ForceOrigin = AssetsForceOrigin;
|
||||
type AssetDeposit = AssetDeposit;
|
||||
type MetadataDepositBase = MetadataDepositBase;
|
||||
type MetadataDepositPerByte = MetadataDepositPerByte;
|
||||
type ApprovalDeposit = ApprovalDeposit;
|
||||
type StringLimit = StringLimit;
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type WeightInfo = weights::pallet_assets::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
|
||||
pub const DepositBase: Balance = deposit(1, 88);
|
||||
// Additional storage item size of 32 bytes.
|
||||
pub const DepositFactor: Balance = deposit(0, 32);
|
||||
pub const MaxSignatories: u16 = 100;
|
||||
}
|
||||
|
||||
impl pallet_multisig::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type Currency = Balances;
|
||||
type DepositBase = DepositBase;
|
||||
type DepositFactor = DepositFactor;
|
||||
type MaxSignatories = MaxSignatories;
|
||||
type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
impl pallet_utility::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size 32, value size 8; .
|
||||
pub const ProxyDepositBase: Balance = deposit(1, 40);
|
||||
// Additional storage item size of 33 bytes.
|
||||
pub const ProxyDepositFactor: Balance = deposit(0, 33);
|
||||
pub const MaxProxies: u16 = 32;
|
||||
// One storage item; key size 32, value size 16
|
||||
pub const AnnouncementDepositBase: Balance = deposit(1, 48);
|
||||
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 {
|
||||
/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
|
||||
Any,
|
||||
/// Can execute any call that does not transfer funds or assets.
|
||||
NonTransfer,
|
||||
/// Proxy with the ability to reject time-delay proxy announcements.
|
||||
CancelProxy,
|
||||
/// Assets proxy. Can execute any call from `assets`, **including asset transfers**.
|
||||
Assets,
|
||||
/// Owner proxy. Can execute calls related to asset ownership.
|
||||
AssetOwner,
|
||||
/// Asset manager. Can execute calls related to asset management.
|
||||
AssetManager,
|
||||
// Collator selection proxy. Can execute calls related to collator selection mechanism.
|
||||
Collator,
|
||||
}
|
||||
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::Assets(pallet_assets::Call::transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_keep_alive(..)) |
|
||||
Call::Assets(pallet_assets::Call::force_transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::approve_transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_approved(..))
|
||||
),
|
||||
ProxyType::CancelProxy => matches!(c,
|
||||
Call::Proxy(pallet_proxy::Call::reject_announcement(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::Assets => {
|
||||
matches!(c, Call::Assets(..) | Call::Utility(..) | Call::Multisig(..))
|
||||
}
|
||||
ProxyType::AssetOwner => matches!(c,
|
||||
Call::Assets(pallet_assets::Call::create(..)) |
|
||||
Call::Assets(pallet_assets::Call::destroy(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
|
||||
Call::Assets(pallet_assets::Call::set_team(..)) |
|
||||
Call::Assets(pallet_assets::Call::set_metadata(..)) |
|
||||
Call::Assets(pallet_assets::Call::clear_metadata(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::AssetManager => matches!(c,
|
||||
Call::Assets(pallet_assets::Call::mint(..)) |
|
||||
Call::Assets(pallet_assets::Call::burn(..)) |
|
||||
Call::Assets(pallet_assets::Call::freeze(..)) |
|
||||
Call::Assets(pallet_assets::Call::thaw(..)) |
|
||||
Call::Assets(pallet_assets::Call::freeze_asset(..)) |
|
||||
Call::Assets(pallet_assets::Call::thaw_asset(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::Collator => matches!(c,
|
||||
Call::CollatorSelection(..) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
)
|
||||
}
|
||||
}
|
||||
fn is_superset(&self, o: &Self) -> bool {
|
||||
match (self, o) {
|
||||
(x, y) if x == y => true,
|
||||
(ProxyType::Any, _) => true,
|
||||
(_, ProxyType::Any) => false,
|
||||
(ProxyType::Assets, ProxyType::AssetOwner) => true,
|
||||
(ProxyType::Assets, ProxyType::AssetManager) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_proxy::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type Currency = Balances;
|
||||
type ProxyType = ProxyType;
|
||||
type ProxyDepositBase = ProxyDepositBase;
|
||||
type ProxyDepositFactor = ProxyDepositFactor;
|
||||
type MaxProxies = MaxProxies;
|
||||
type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
|
||||
type MaxPending = MaxPending;
|
||||
type CallHasher = BlakeTwo256;
|
||||
type AnnouncementDepositBase = AnnouncementDepositBase;
|
||||
type AnnouncementDepositFactor = AnnouncementDepositFactor;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_parachain_system::Config for Runtime {
|
||||
type Event = Event;
|
||||
type OnValidationData = ();
|
||||
type SelfParaId = parachain_info::Pallet<Runtime>;
|
||||
type DmpMessageHandler = DmpQueue;
|
||||
type ReservedDmpWeight = ReservedDmpWeight;
|
||||
type OutboundXcmpMessageSource = XcmpQueue;
|
||||
type XcmpMessageHandler = XcmpQueue;
|
||||
type ReservedXcmpWeight = ReservedXcmpWeight;
|
||||
}
|
||||
|
||||
impl parachain_info::Config for Runtime {}
|
||||
|
||||
impl cumulus_pallet_aura_ext::Config for Runtime {}
|
||||
|
||||
parameter_types! {
|
||||
pub const KsmLocation: MultiLocation = MultiLocation::X1(Junction::Parent);
|
||||
pub const RelayNetwork: NetworkId = NetworkId::Kusama;
|
||||
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub Ancestry: MultiLocation = Junction::Parachain(ParachainInfo::parachain_id().into()).into();
|
||||
}
|
||||
|
||||
/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
|
||||
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
|
||||
/// `Transact` in order to determine the dispatch Origin.
|
||||
pub type LocationToAccountId = (
|
||||
// The parent (Relay-chain) origin converts to the default `AccountId`.
|
||||
ParentIsDefault<AccountId>,
|
||||
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
|
||||
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
|
||||
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||
);
|
||||
|
||||
/// Means for transacting assets on this chain.
|
||||
pub type LocalAssetTransactor = CurrencyAdapter<
|
||||
// Use this currency:
|
||||
Balances,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
IsConcrete<KsmLocation>,
|
||||
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
AccountId,
|
||||
// We don't track any teleports.
|
||||
(),
|
||||
>;
|
||||
|
||||
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
|
||||
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
|
||||
/// biases the kind of local `Origin` it will become.
|
||||
pub type XcmOriginToTransactDispatchOrigin = (
|
||||
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
|
||||
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
|
||||
// foreign chains who want to have a local sovereign account on this chain which they control.
|
||||
SovereignSignedViaLocation<LocationToAccountId, Origin>,
|
||||
// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
|
||||
// recognised.
|
||||
RelayChainAsNative<RelayChainOrigin, Origin>,
|
||||
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
|
||||
// recognised.
|
||||
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
|
||||
// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
|
||||
// transaction from the Root origin.
|
||||
ParentAsSuperuser<Origin>,
|
||||
// Native signed account converter; this just converts an `AccountId32` origin into a normal
|
||||
// `Origin::Signed` origin of the same 32-byte value.
|
||||
SignedAccountId32AsNative<RelayNetwork, Origin>,
|
||||
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
|
||||
XcmPassthrough<Origin>,
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
// One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
|
||||
pub UnitWeightCost: Weight = 1_000_000;
|
||||
}
|
||||
|
||||
match_type! {
|
||||
pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {
|
||||
MultiLocation::X1(Junction::Parent) |
|
||||
MultiLocation::X2(Junction::Parent, Junction::Plurality { id: BodyId::Executive, .. })
|
||||
};
|
||||
}
|
||||
|
||||
pub type Barrier = (
|
||||
TakeWeightCredit,
|
||||
AllowTopLevelPaidExecutionFrom<All<MultiLocation>>,
|
||||
AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
|
||||
// ^^^ Parent and its exec plurality get free execution
|
||||
);
|
||||
|
||||
pub struct XcmConfig;
|
||||
impl Config for XcmConfig {
|
||||
type Call = Call;
|
||||
type XcmSender = XcmRouter;
|
||||
// How to withdraw and deposit an asset.
|
||||
type AssetTransactor = LocalAssetTransactor;
|
||||
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||
type IsReserve = NativeAsset;
|
||||
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of KSM
|
||||
type LocationInverter = LocationInverter<Ancestry>;
|
||||
type Barrier = Barrier;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
|
||||
type Trader = UsingComponents<IdentityFee<Balance>, KsmLocation, AccountId, Balances, ()>;
|
||||
type ResponseHandler = (); // Don't handle responses for now.
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
|
||||
}
|
||||
|
||||
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
|
||||
pub type LocalOriginToLocation = (
|
||||
SignedToAccountId32<Origin, AccountId, RelayNetwork>,
|
||||
);
|
||||
|
||||
/// The means for routing XCM messages which are not for local execution into the right message
|
||||
/// queues.
|
||||
pub type XcmRouter = (
|
||||
// Two routers - use UMP to communicate with the relay chain:
|
||||
cumulus_primitives_utility::ParentAsUmp<ParachainSystem>,
|
||||
// ..and XCMP to communicate with the sibling chains.
|
||||
XcmpQueue,
|
||||
);
|
||||
|
||||
impl pallet_xcm::Config for Runtime {
|
||||
type Event = Event;
|
||||
type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||
type XcmRouter = XcmRouter;
|
||||
type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||
type XcmExecuteFilter = All<(MultiLocation, Xcm<Call>)>;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
|
||||
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_xcm::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_xcmp_queue::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type ChannelInfo = ParachainSystem;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_dmp_queue::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33);
|
||||
pub const Period: u32 = 6 * HOURS;
|
||||
pub const Offset: u32 = 0;
|
||||
}
|
||||
|
||||
impl pallet_session::Config for Runtime {
|
||||
type Event = Event;
|
||||
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||
// we don't have stash and controller, thus we don't need the convert as well.
|
||||
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionManager = CollatorSelection;
|
||||
// Essentially just Aura, but lets be pedantic.
|
||||
type SessionHandler = <opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
||||
type Keys = opaque::SessionKeys;
|
||||
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
impl pallet_aura::Config for Runtime {
|
||||
type AuthorityId = AuraId;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const PotId: PalletId = PalletId(*b"PotStake");
|
||||
pub const MaxCandidates: u32 = 1000;
|
||||
pub const SessionLength: BlockNumber = 6 * HOURS;
|
||||
pub const MaxInvulnerables: u32 = 100;
|
||||
}
|
||||
|
||||
/// We allow root and the Relay Chain council to execute privileged collator selection operations.
|
||||
pub type CollatorSelectionUpdateOrigin = EnsureOneOf<
|
||||
AccountId,
|
||||
EnsureRoot<AccountId>,
|
||||
EnsureXcm<IsMajorityOfBody<KsmLocation, ExecutiveBody>>,
|
||||
>;
|
||||
|
||||
impl pallet_collator_selection::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Currency = Balances;
|
||||
type UpdateOrigin = CollatorSelectionUpdateOrigin;
|
||||
type PotId = PotId;
|
||||
type MaxCandidates = MaxCandidates;
|
||||
type MaxInvulnerables = MaxInvulnerables;
|
||||
// should be a multiple of session or things will get inconsistent
|
||||
type KickThreshold = Period;
|
||||
type WeightInfo = weights::pallet_collator_selection::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
// Create the runtime by composing the FRAME pallets that were previously configured.
|
||||
construct_runtime!(
|
||||
pub enum Runtime where
|
||||
Block = Block,
|
||||
NodeBlock = opaque::Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
{
|
||||
// System support stuff.
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>} = 0,
|
||||
ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 1,
|
||||
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Call, Storage} = 2,
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
|
||||
ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4,
|
||||
|
||||
// Monetary stuff.
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 10,
|
||||
TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 11,
|
||||
|
||||
// Collator support. the order of these 4 are important and shall not change.
|
||||
Authorship: pallet_authorship::{Pallet, Call, Storage} = 20,
|
||||
CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>, Config<T>} = 21,
|
||||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 22,
|
||||
Aura: pallet_aura::{Pallet, Storage, Config<T>} = 23,
|
||||
AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24,
|
||||
|
||||
// XCM helpers.
|
||||
XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 30,
|
||||
PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 31,
|
||||
CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 32,
|
||||
DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 33,
|
||||
|
||||
// Handy utilities.
|
||||
Utility: pallet_utility::{Pallet, Call, Event} = 40,
|
||||
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 41,
|
||||
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 42,
|
||||
|
||||
// The main stage. To include pallet-assets-freezer and pallet-uniques.
|
||||
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 50,
|
||||
}
|
||||
);
|
||||
|
||||
/// The address format for describing accounts.
|
||||
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
|
||||
/// Block type as expected by this runtime.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// A Block signed with a Justification
|
||||
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
/// BlockId type as expected by this runtime.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
/// The SignedExtension to the basic transaction logic.
|
||||
pub type SignedExtra = (
|
||||
frame_system::CheckSpecVersion<Runtime>,
|
||||
frame_system::CheckTxVersion<Runtime>,
|
||||
frame_system::CheckGenesis<Runtime>,
|
||||
frame_system::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>;
|
||||
/// 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,
|
||||
>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||
fn slot_duration() -> sp_consensus_aura::SlotDuration {
|
||||
sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuraId> {
|
||||
Aura::authorities()
|
||||
}
|
||||
}
|
||||
|
||||
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: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
|
||||
data.create_extrinsics()
|
||||
}
|
||||
|
||||
fn check_inherents(
|
||||
block: Block,
|
||||
data: sp_inherents::InherentData,
|
||||
) -> sp_inherents::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 sp_session::SessionKeys<Block> for Runtime {
|
||||
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
|
||||
opaque::SessionKeys::generate(seed)
|
||||
}
|
||||
|
||||
fn decode_session_keys(
|
||||
encoded: Vec<u8>,
|
||||
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
|
||||
opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
|
||||
fn account_nonce(account: AccountId) -> Index {
|
||||
System::account_nonce(account)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
|
||||
fn query_info(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
|
||||
TransactionPayment::query_info(uxt, len)
|
||||
}
|
||||
fn query_fee_details(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment::FeeDetails<Balance> {
|
||||
TransactionPayment::query_fee_details(uxt, len)
|
||||
}
|
||||
}
|
||||
|
||||
impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
|
||||
fn collect_collation_info() -> cumulus_primitives_core::CollationInfo {
|
||||
ParachainSystem::collect_collation_info()
|
||||
}
|
||||
}
|
||||
|
||||
#[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};
|
||||
|
||||
use frame_system_benchmarking::Pallet as SystemBench;
|
||||
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(),
|
||||
];
|
||||
|
||||
let mut batches = Vec::<BenchmarkBatch>::new();
|
||||
let params = (&config, &whitelist);
|
||||
|
||||
add_benchmark!(params, batches, frame_system, SystemBench::<Runtime>);
|
||||
add_benchmark!(params, batches, pallet_assets, Assets);
|
||||
add_benchmark!(params, batches, pallet_balances, Balances);
|
||||
add_benchmark!(params, batches, pallet_multisig, Multisig);
|
||||
add_benchmark!(params, batches, pallet_proxy, Proxy);
|
||||
add_benchmark!(params, batches, pallet_utility, Utility);
|
||||
add_benchmark!(params, batches, pallet_timestamp, Timestamp);
|
||||
add_benchmark!(params, batches, pallet_collator_selection, CollatorSelection);
|
||||
|
||||
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
|
||||
Ok(batches)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cumulus_pallet_parachain_system::register_validate_block!(
|
||||
Runtime,
|
||||
cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
pub mod pallet_assets;
|
||||
pub mod pallet_balances;
|
||||
pub mod pallet_multisig;
|
||||
pub mod pallet_collator_selection;
|
||||
pub mod pallet_proxy;
|
||||
pub mod pallet_timestamp;
|
||||
pub mod pallet_utility;
|
||||
@@ -0,0 +1,161 @@
|
||||
|
||||
//! Autogenerated weights for pallet_assets
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_assets
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_assets.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_assets::WeightInfo for WeightInfo<T> {
|
||||
fn create() -> Weight {
|
||||
(44_224_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_create() -> Weight {
|
||||
(22_533_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn destroy(c: u32, s: u32, a: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 37_000
|
||||
.saturating_add((21_529_000 as Weight).saturating_mul(c as Weight))
|
||||
// Standard Error: 37_000
|
||||
.saturating_add((28_905_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 377_000
|
||||
.saturating_add((3_745_000 as Weight).saturating_mul(a as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(s as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(s as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(a as Weight)))
|
||||
}
|
||||
fn mint() -> Weight {
|
||||
(49_078_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn burn() -> Weight {
|
||||
(55_886_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn transfer() -> Weight {
|
||||
(84_857_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn transfer_keep_alive() -> Weight {
|
||||
(71_330_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn force_transfer() -> Weight {
|
||||
(85_127_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn freeze() -> Weight {
|
||||
(31_403_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn thaw() -> Weight {
|
||||
(31_250_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn freeze_asset() -> Weight {
|
||||
(22_097_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn thaw_asset() -> Weight {
|
||||
(22_245_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_ownership() -> Weight {
|
||||
(25_479_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_team() -> Weight {
|
||||
(22_271_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_metadata(_n: u32, s: u32, ) -> Weight {
|
||||
(50_315_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((8_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn clear_metadata() -> Weight {
|
||||
(48_134_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_set_metadata(_n: u32, s: u32, ) -> Weight {
|
||||
(25_933_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((7_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_clear_metadata() -> Weight {
|
||||
(49_243_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_asset_status() -> Weight {
|
||||
(22_305_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_transfer() -> Weight {
|
||||
(48_885_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_approved() -> Weight {
|
||||
(108_026_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(5 as Weight))
|
||||
}
|
||||
fn cancel_approval() -> Weight {
|
||||
(48_943_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_cancel_approval() -> Weight {
|
||||
(56_914_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
//! Autogenerated weights for pallet_balances
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_balances
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_balances.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
|
||||
fn transfer() -> Weight {
|
||||
(79_381_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_keep_alive() -> Weight {
|
||||
(58_057_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_balance_creating() -> Weight {
|
||||
(28_834_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_balance_killing() -> Weight {
|
||||
(36_213_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_transfer() -> Weight {
|
||||
(78_526_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
//! Autogenerated weights for pallet_collator_selection
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_collator_selection
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_collator_selection.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_collator_selection::WeightInfo for WeightInfo<T> {
|
||||
fn set_invulnerables(b: u32, ) -> Weight {
|
||||
(18_481_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((67_000 as Weight).saturating_mul(b as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_desired_candidates() -> Weight {
|
||||
(16_376_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_candidacy_bond() -> Weight {
|
||||
(17_031_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn register_as_candidate(c: u32, ) -> Weight {
|
||||
(72_345_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((197_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn leave_intent(c: u32, ) -> Weight {
|
||||
(55_446_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((153_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn note_author() -> Weight {
|
||||
(71_828_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn new_session(r: u32, c: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 1_004_000
|
||||
.saturating_add((110_066_000 as Weight).saturating_mul(r as Weight))
|
||||
// Standard Error: 1_004_000
|
||||
.saturating_add((152_035_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
//! Autogenerated weights for pallet_multisig
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_multisig
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_multisig.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_multisig::WeightInfo for WeightInfo<T> {
|
||||
fn as_multi_threshold_1(z: u32, ) -> Weight {
|
||||
(15_911_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
}
|
||||
fn as_multi_create(s: u32, z: u32, ) -> Weight {
|
||||
(55_326_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((133_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn as_multi_create_store(s: u32, z: u32, ) -> Weight {
|
||||
(62_423_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((133_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((3_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn as_multi_approve(s: u32, z: u32, ) -> Weight {
|
||||
(32_430_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((148_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn as_multi_approve_store(s: u32, z: u32, ) -> Weight {
|
||||
(59_789_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((165_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((3_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn as_multi_complete(s: u32, z: u32, ) -> Weight {
|
||||
(80_926_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((276_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((5_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn approve_as_multi_create(s: u32, ) -> Weight {
|
||||
(54_860_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((134_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_as_multi_approve(s: u32, ) -> Weight {
|
||||
(31_924_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((154_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_as_multi_complete(s: u32, ) -> Weight {
|
||||
(154_001_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((281_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn cancel_as_multi(s: u32, ) -> Weight {
|
||||
(103_770_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((130_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
//! Autogenerated weights for pallet_proxy
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_proxy
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_proxy.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_proxy::WeightInfo for WeightInfo<T> {
|
||||
fn proxy(p: u32, ) -> Weight {
|
||||
(27_318_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((208_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
}
|
||||
fn proxy_announced(a: u32, p: u32, ) -> Weight {
|
||||
(60_665_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((677_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((197_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn remove_announcement(a: u32, p: u32, ) -> Weight {
|
||||
(39_455_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((687_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((3_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn reject_announcement(a: u32, p: u32, ) -> Weight {
|
||||
(39_411_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((686_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((3_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn announce(a: u32, p: u32, ) -> Weight {
|
||||
(54_386_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((677_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((194_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn add_proxy(p: u32, ) -> Weight {
|
||||
(37_411_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((298_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn remove_proxy(p: u32, ) -> Weight {
|
||||
(36_658_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((332_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn remove_proxies(p: u32, ) -> Weight {
|
||||
(34_893_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((209_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn anonymous(p: u32, ) -> Weight {
|
||||
(51_243_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((44_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn kill_anonymous(p: u32, ) -> Weight {
|
||||
(37_188_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((208_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
//! Autogenerated weights for pallet_timestamp
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_timestamp
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_timestamp.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_timestamp::WeightInfo for WeightInfo<T> {
|
||||
fn set() -> Weight {
|
||||
(7_543_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn on_finalize() -> Weight {
|
||||
(4_272_000 as Weight)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
//! Autogenerated weights for pallet_utility
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemine-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemine-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_utility
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemine/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_utility.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
|
||||
fn batch(c: u32, ) -> Weight {
|
||||
(16_177_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((4_582_000 as Weight).saturating_mul(c as Weight))
|
||||
}
|
||||
fn as_derivative() -> Weight {
|
||||
(7_848_000 as Weight)
|
||||
}
|
||||
fn batch_all(c: u32, ) -> Weight {
|
||||
(17_745_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((4_578_000 as Weight).saturating_mul(c as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
[package]
|
||||
name = "statemint-common"
|
||||
version = "1.0.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
description = "Logic which is common to all Statemint variant runtimes"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ['x86_64-unknown-linux-gnu']
|
||||
|
||||
[dependencies]
|
||||
# External dependencies
|
||||
codec = { package = 'parity-scale-codec', version = '2.0.0', features = ['derive'], default-features = false }
|
||||
|
||||
# Substrate dependencies
|
||||
sp-consensus-aura = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
sp-std = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
sp-io = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
frame-executive = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
frame-support = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
frame-system = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
pallet-balances = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
sp-runtime = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
sp-core = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
node-primitives = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
|
||||
# Polkadot dependencies
|
||||
polkadot-runtime-common = { git = 'https://github.com/paritytech/polkadot', branch = "master", default-features = false }
|
||||
polkadot-primitives = { git = 'https://github.com/paritytech/polkadot', branch = "master", default-features = false }
|
||||
|
||||
# Local dependencies
|
||||
pallet-collator-selection = { path = '../../pallets/collator-selection', default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1.0.119" }
|
||||
sp-io = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
pallet-authorship = { git = 'https://github.com/paritytech/substrate', branch = "master", default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { git = 'https://github.com/paritytech/substrate', branch = "master" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
'codec/std',
|
||||
'sp-consensus-aura/std',
|
||||
'sp-std/std',
|
||||
'sp-io/std',
|
||||
'frame-support/std',
|
||||
'frame-executive/std',
|
||||
'frame-system/std',
|
||||
'pallet-collator-selection/std',
|
||||
'pallet-balances/std',
|
||||
'node-primitives/std',
|
||||
'polkadot-runtime-common/std',
|
||||
'polkadot-primitives/std',
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Auxillary struct/enums for Statemint runtime.
|
||||
//! Taken from polkadot/runtime/common (at a21cd64) and adapted for Statemint.
|
||||
|
||||
use frame_support::traits::{Currency, Imbalance, OnUnbalanced};
|
||||
|
||||
pub type NegativeImbalance<T> = <pallet_balances::Pallet<T> as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
|
||||
|
||||
/// Logic for the author to get a portion of fees.
|
||||
pub struct ToStakingPot<R>(sp_std::marker::PhantomData<R>);
|
||||
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToStakingPot<R>
|
||||
where
|
||||
R: pallet_balances::Config + pallet_collator_selection::Config,
|
||||
<R as frame_system::Config>::AccountId: From<polkadot_primitives::v1::AccountId>,
|
||||
<R as frame_system::Config>::AccountId: Into<polkadot_primitives::v1::AccountId>,
|
||||
<R as frame_system::Config>::Event: From<pallet_balances::Event<R>>,
|
||||
{
|
||||
fn on_nonzero_unbalanced(amount: NegativeImbalance<R>) {
|
||||
let numeric_amount = amount.peek();
|
||||
let staking_pot = <pallet_collator_selection::Pallet<R>>::account_id();
|
||||
<pallet_balances::Pallet<R>>::resolve_creating(
|
||||
&staking_pot,
|
||||
amount,
|
||||
);
|
||||
<frame_system::Pallet<R>>::deposit_event(pallet_balances::Event::Deposit(
|
||||
staking_pot,
|
||||
numeric_amount,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DealWithFees<R>(sp_std::marker::PhantomData<R>);
|
||||
impl<R> OnUnbalanced<NegativeImbalance<R>> for DealWithFees<R>
|
||||
where
|
||||
R: pallet_balances::Config + pallet_collator_selection::Config,
|
||||
<R as frame_system::Config>::AccountId: From<polkadot_primitives::v1::AccountId>,
|
||||
<R as frame_system::Config>::AccountId: Into<polkadot_primitives::v1::AccountId>,
|
||||
<R as frame_system::Config>::Event: From<pallet_balances::Event<R>>,
|
||||
{
|
||||
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance<R>>) {
|
||||
if let Some(mut fees) = fees_then_tips.next() {
|
||||
if let Some(tips) = fees_then_tips.next() {
|
||||
tips.merge_into(&mut fees);
|
||||
}
|
||||
<ToStakingPot<R> as OnUnbalanced<_>>::on_unbalanced(fees);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use frame_support::traits::FindAuthor;
|
||||
use frame_support::{parameter_types, weights::DispatchClass, PalletId};
|
||||
use frame_system::{limits, EnsureRoot};
|
||||
use polkadot_primitives::v1::AccountId;
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
Perbill,
|
||||
};
|
||||
|
||||
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
|
||||
type Block = frame_system::mocking::MockBlock<Test>;
|
||||
|
||||
frame_support::construct_runtime!(
|
||||
pub enum Test where
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
{
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||
CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>},
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
|
||||
.for_class(DispatchClass::all(), |weight| {
|
||||
weight.base_extrinsic = 100;
|
||||
})
|
||||
.for_class(DispatchClass::non_mandatory(), |weight| {
|
||||
weight.max_total = Some(1024);
|
||||
})
|
||||
.build_or_panic();
|
||||
pub BlockLength: limits::BlockLength = limits::BlockLength::max(2 * 1024);
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::one();
|
||||
}
|
||||
|
||||
impl frame_system::Config for Test {
|
||||
type BaseCallFilter = ();
|
||||
type Origin = Origin;
|
||||
type Index = u64;
|
||||
type BlockNumber = u64;
|
||||
type Call = Call;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = AccountId;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type BlockLength = BlockLength;
|
||||
type BlockWeights = BlockWeights;
|
||||
type DbWeight = ();
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = pallet_balances::AccountData<u64>;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = ();
|
||||
type OnSetCode = ();
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Test {
|
||||
type Balance = u64;
|
||||
type Event = Event;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ();
|
||||
type AccountStore = System;
|
||||
type MaxLocks = ();
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
pub struct OneAuthor;
|
||||
impl FindAuthor<AccountId> for OneAuthor {
|
||||
fn find_author<'a, I>(_: I) -> Option<AccountId>
|
||||
where
|
||||
I: 'a,
|
||||
{
|
||||
Some(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const PotId: PalletId = PalletId(*b"PotStake");
|
||||
pub const MaxCandidates: u32 = 20;
|
||||
pub const MaxInvulnerables: u32 = 20;
|
||||
}
|
||||
|
||||
impl pallet_collator_selection::Config for Test {
|
||||
type Event = Event;
|
||||
type Currency = Balances;
|
||||
type UpdateOrigin = EnsureRoot<AccountId>;
|
||||
type PotId = PotId;
|
||||
type MaxCandidates = MaxCandidates;
|
||||
type MaxInvulnerables = MaxInvulnerables;
|
||||
type KickThreshold = ();
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
impl pallet_authorship::Config for Test {
|
||||
type FindAuthor = OneAuthor;
|
||||
type UncleGenerations = ();
|
||||
type FilterUncle = ();
|
||||
type EventHandler = ();
|
||||
}
|
||||
|
||||
pub fn new_test_ext() -> sp_io::TestExternalities {
|
||||
let mut t = frame_system::GenesisConfig::default()
|
||||
.build_storage::<Test>()
|
||||
.unwrap();
|
||||
// We use default for brevity, but you can configure as desired if needed.
|
||||
pallet_balances::GenesisConfig::<Test>::default()
|
||||
.assimilate_storage(&mut t)
|
||||
.unwrap();
|
||||
t.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fees_and_tip_split() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let fee = Balances::issue(10);
|
||||
let tip = Balances::issue(20);
|
||||
|
||||
assert_eq!(Balances::free_balance(AccountId::default()), 0);
|
||||
|
||||
DealWithFees::on_unbalanceds(vec![fee, tip].into_iter());
|
||||
|
||||
// Author gets 100% of tip and 100% of fee = 30
|
||||
assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 30);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
pub mod impls;
|
||||
pub use types::*;
|
||||
pub use constants::*;
|
||||
|
||||
/// Common types of statemint and statemine.
|
||||
mod types {
|
||||
use sp_runtime::traits::{Verify, IdentifyAccount, BlakeTwo256};
|
||||
|
||||
/// An index to a block.
|
||||
pub type BlockNumber = u32;
|
||||
|
||||
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
||||
pub type Signature = sp_runtime::MultiSignature;
|
||||
|
||||
/// Some way of identifying an account on the chain. We intentionally make it equivalent
|
||||
/// to the public key of our transaction signing scheme.
|
||||
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
|
||||
|
||||
/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
|
||||
/// never know...
|
||||
pub type AccountIndex = u32;
|
||||
|
||||
/// Balance of an account.
|
||||
pub type Balance = u128;
|
||||
|
||||
/// Index of a transaction in the chain.
|
||||
pub type Index = u32;
|
||||
|
||||
/// A hash of some data used by the chain.
|
||||
pub type Hash = sp_core::H256;
|
||||
|
||||
/// Block header type as expected by this runtime.
|
||||
pub type Header = sp_runtime::generic::Header<BlockNumber, BlakeTwo256>;
|
||||
|
||||
/// Digest item type.
|
||||
pub type DigestItem = sp_runtime::generic::DigestItem<Hash>;
|
||||
|
||||
// Aura consensus authority.
|
||||
pub type AuraId = sp_consensus_aura::sr25519::AuthorityId;
|
||||
}
|
||||
|
||||
/// Common constants of statemint and statemine
|
||||
mod constants {
|
||||
use super::types::BlockNumber;
|
||||
use sp_runtime::Perbill;
|
||||
use frame_support::weights::{Weight, constants::WEIGHT_PER_SECOND};
|
||||
/// This determines the average expected block time that we are targeting. Blocks will be
|
||||
/// produced at a minimum duration defined by `SLOT_DURATION`. `SLOT_DURATION` is picked up by
|
||||
/// `pallet_timestamp` which is in turn picked up by `pallet_aura` to implement `fn
|
||||
/// slot_duration()`.
|
||||
///
|
||||
/// Change this to adjust the block time.
|
||||
pub const MILLISECS_PER_BLOCK: u64 = 12000;
|
||||
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
|
||||
|
||||
// Time is measured by number of blocks.
|
||||
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
|
||||
pub const HOURS: BlockNumber = MINUTES * 60;
|
||||
pub const DAYS: BlockNumber = HOURS * 24;
|
||||
|
||||
/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
|
||||
/// used to limit the maximal weight of a single extrinsic.
|
||||
pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
|
||||
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
|
||||
/// Operational extrinsics.
|
||||
pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
|
||||
|
||||
/// We allow for 0.5 seconds of compute with a 6 second average block time.
|
||||
pub const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
[package]
|
||||
name = 'statemint-runtime'
|
||||
version = '1.0.0'
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = '2018'
|
||||
description = "Statemint parachain runtime"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
|
||||
log = { version = "0.4.14", default-features = false }
|
||||
parachain-info = { path = "../pallets/parachain-info", default-features = false }
|
||||
smallvec = "1.6.1"
|
||||
hex-literal = { version = '0.3.1', optional = true }
|
||||
|
||||
# Substrate dependencies
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
frame-benchmarking = { git = "https://github.com/paritytech/substrate", optional = true, default-features = false, branch = "master" }
|
||||
frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", optional = true, default-features = false, branch = "master" }
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-assets = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-authorship = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-multisig = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-proxy = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-utility = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
node-primitives = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
max-encoded-len = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
# Cumulus dependencies
|
||||
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
|
||||
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
|
||||
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
||||
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
|
||||
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
|
||||
cumulus-pallet-xcm = { path = "../../pallets/xcm", default-features = false }
|
||||
cumulus-ping = { path = "../pallets/ping", default-features = false }
|
||||
pallet-collator-selection = { path = "../../pallets/collator-selection", default-features = false }
|
||||
statemint-common = { path = "../statemint-common", default-features = false }
|
||||
|
||||
# Polkadot dependencies
|
||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.3.1"
|
||||
hex = "0.4.3"
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
runtime-benchmarks = [
|
||||
'hex-literal',
|
||||
'sp-runtime/runtime-benchmarks',
|
||||
'xcm-builder/runtime-benchmarks',
|
||||
'frame-benchmarking',
|
||||
'frame-system-benchmarking',
|
||||
'frame-support/runtime-benchmarks',
|
||||
'frame-system/runtime-benchmarks',
|
||||
'pallet-assets/runtime-benchmarks',
|
||||
'pallet-balances/runtime-benchmarks',
|
||||
'pallet-multisig/runtime-benchmarks',
|
||||
'pallet-proxy/runtime-benchmarks',
|
||||
'pallet-utility/runtime-benchmarks',
|
||||
'pallet-timestamp/runtime-benchmarks',
|
||||
'pallet-xcm/runtime-benchmarks',
|
||||
'pallet-collator-selection/runtime-benchmarks',
|
||||
]
|
||||
std = [
|
||||
"codec/std",
|
||||
"serde",
|
||||
"log/std",
|
||||
"sp-api/std",
|
||||
"sp-std/std",
|
||||
"sp-io/std",
|
||||
"sp-core/std",
|
||||
"sp-runtime/std",
|
||||
"sp-version/std",
|
||||
"sp-offchain/std",
|
||||
"sp-session/std",
|
||||
"sp-block-builder/std",
|
||||
"sp-transaction-pool/std",
|
||||
"sp-inherents/std",
|
||||
"frame-support/std",
|
||||
"frame-executive/std",
|
||||
"frame-system/std",
|
||||
"frame-system-rpc-runtime-api/std",
|
||||
"pallet-assets/std",
|
||||
"pallet-authorship/std",
|
||||
"pallet-aura/std",
|
||||
"pallet-balances/std",
|
||||
"pallet-multisig/std",
|
||||
"pallet-proxy/std",
|
||||
"pallet-randomness-collective-flip/std",
|
||||
"pallet-session/std",
|
||||
"pallet-sudo/std",
|
||||
"pallet-timestamp/std",
|
||||
"pallet-transaction-payment/std",
|
||||
"pallet-transaction-payment-rpc-runtime-api/std",
|
||||
"pallet-utility/std",
|
||||
"parachain-info/std",
|
||||
"cumulus-pallet-aura-ext/std",
|
||||
"pallet-collator-selection/std",
|
||||
"cumulus-pallet-dmp-queue/std",
|
||||
"cumulus-pallet-parachain-system/std",
|
||||
"cumulus-pallet-xcmp-queue/std",
|
||||
"cumulus-pallet-xcm/std",
|
||||
"cumulus-primitives-core/std",
|
||||
"cumulus-primitives-utility/std",
|
||||
"cumulus-ping/std",
|
||||
"xcm/std",
|
||||
"xcm-builder/std",
|
||||
"xcm-executor/std",
|
||||
"sp-consensus-aura/std",
|
||||
"node-primitives/std",
|
||||
"statemint-common/std",
|
||||
]
|
||||
@@ -0,0 +1,9 @@
|
||||
use substrate_wasm_builder::WasmBuilder;
|
||||
|
||||
fn main() {
|
||||
WasmBuilder::new()
|
||||
.with_current_project()
|
||||
.export_heap_base()
|
||||
.import_memory()
|
||||
.build()
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub mod currency {
|
||||
use node_primitives::Balance;
|
||||
|
||||
/// The existential deposit. Set to 1/10 of its parent Relay Chain (v9010).
|
||||
pub const EXISTENTIAL_DEPOSIT: Balance = 10 * CENTS;
|
||||
|
||||
pub const UNITS: Balance = 10_000_000_000;
|
||||
pub const DOLLARS: Balance = UNITS;
|
||||
pub const CENTS: Balance = UNITS / 100; // 100_000_000
|
||||
pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000
|
||||
|
||||
pub const fn deposit(items: u32, bytes: u32) -> Balance {
|
||||
// 1/10 of Polkadot v9010
|
||||
(items as Balance * 20 * DOLLARS + (bytes as Balance) * 100 * MILLICENTS) / 10
|
||||
}
|
||||
}
|
||||
|
||||
/// Fee-related.
|
||||
pub mod fee {
|
||||
use node_primitives::Balance;
|
||||
pub use sp_runtime::Perbill;
|
||||
use frame_support::weights::{
|
||||
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
|
||||
WeightToFeePolynomial,
|
||||
};
|
||||
use smallvec::smallvec;
|
||||
|
||||
/// The block saturation level. Fees will be updates based on this value.
|
||||
pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
|
||||
|
||||
/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
|
||||
/// node's balance type.
|
||||
///
|
||||
/// This should typically create a mapping between the following ranges:
|
||||
/// - [0, MAXIMUM_BLOCK_WEIGHT]
|
||||
/// - [Balance::min, Balance::max]
|
||||
///
|
||||
/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
|
||||
/// - Setting it to `0` will essentially disable the weight fee.
|
||||
/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
|
||||
pub struct WeightToFee;
|
||||
impl WeightToFeePolynomial for WeightToFee {
|
||||
type Balance = Balance;
|
||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||
// in Statemint, we map to 1/10 of that, or 1/100 CENT
|
||||
let p = super::currency::CENTS;
|
||||
let q = 100 * Balance::from(ExtrinsicBaseWeight::get());
|
||||
smallvec![WeightToFeeCoefficient {
|
||||
degree: 1,
|
||||
negative: false,
|
||||
coeff_frac: Perbill::from_rational(p % q, q),
|
||||
coeff_integer: p / q,
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,827 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Statemint runtime.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
// Make the WASM binary available.
|
||||
#[cfg(feature = "std")]
|
||||
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
|
||||
pub mod constants;
|
||||
mod weights;
|
||||
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||
use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT};
|
||||
use sp_runtime::{
|
||||
create_runtime_str, generic, impl_opaque_keys,
|
||||
transaction_validity::{TransactionSource, TransactionValidity},
|
||||
ApplyExtrinsicResult,
|
||||
};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_version::NativeVersion;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
use frame_system::{
|
||||
EnsureOneOf, EnsureRoot, limits::{BlockLength, BlockWeights},
|
||||
};
|
||||
use statemint_common::{
|
||||
BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId, Header,
|
||||
NORMAL_DISPATCH_RATIO, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, SLOT_DURATION, HOURS,
|
||||
};
|
||||
pub use statemint_common as common;
|
||||
use statemint_common::impls::DealWithFees;
|
||||
use codec::{Decode, Encode};
|
||||
use constants::{currency::*, fee::WeightToFee};
|
||||
use frame_support::{
|
||||
construct_runtime, parameter_types, match_type,
|
||||
traits::{InstanceFilter, All, MaxEncodedLen},
|
||||
weights::{
|
||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
|
||||
DispatchClass, IdentityFee, Weight,
|
||||
},
|
||||
RuntimeDebug, PalletId,
|
||||
};
|
||||
use sp_runtime::Perbill;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
|
||||
// Polkadot imports
|
||||
use polkadot_parachain::primitives::Sibling;
|
||||
use polkadot_runtime_common::{
|
||||
BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate,
|
||||
};
|
||||
use xcm::v0::{MultiAsset, Junction, MultiLocation, NetworkId, Xcm, BodyId};
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
|
||||
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
|
||||
SovereignSignedViaLocation, EnsureXcmOrigin,
|
||||
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
|
||||
AllowUnpaidExecutionFrom, ParentAsSuperuser, SignedToAccountId32, UsingComponents,
|
||||
};
|
||||
use xcm_executor::{Config, XcmExecutor};
|
||||
use pallet_xcm::{XcmPassthrough, EnsureXcm, IsMajorityOfBody};
|
||||
|
||||
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
|
||||
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
|
||||
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
|
||||
/// to even the core data structures.
|
||||
pub mod opaque {
|
||||
use super::*;
|
||||
pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
|
||||
/// Opaque block header type.
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
||||
/// Opaque block type.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// Opaque block identifier type.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
impl_opaque_keys! {
|
||||
pub struct SessionKeys {
|
||||
pub aura: Aura,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[sp_version::runtime_version]
|
||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("statemint"),
|
||||
impl_name: create_runtime_str!("statemint"),
|
||||
authoring_version: 1,
|
||||
spec_version: 1,
|
||||
impl_version: 1,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
};
|
||||
|
||||
/// The version information used to identify this runtime when compiled natively.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn native_version() -> NativeVersion {
|
||||
NativeVersion {
|
||||
runtime_version: VERSION,
|
||||
can_author_with: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
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 = 0;
|
||||
}
|
||||
|
||||
// Configure FRAME pallets to include in runtime.
|
||||
impl frame_system::Config for Runtime {
|
||||
type BaseCallFilter = ();
|
||||
type BlockWeights = RuntimeBlockWeights;
|
||||
type BlockLength = RuntimeBlockLength;
|
||||
type AccountId = AccountId;
|
||||
type Call = Call;
|
||||
type Lookup = AccountIdLookup<AccountId, ()>;
|
||||
type Index = Index;
|
||||
type BlockNumber = BlockNumber;
|
||||
type Hash = Hash;
|
||||
type Hashing = BlakeTwo256;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type Origin = Origin;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type DbWeight = RocksDbWeight;
|
||||
type Version = Version;
|
||||
type PalletInfo = PalletInfo;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type AccountData = pallet_balances::AccountData<Balance>;
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
||||
}
|
||||
|
||||
impl pallet_timestamp::Config for Runtime {
|
||||
/// A timestamp: milliseconds since the unix epoch.
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = ();
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const UncleGenerations: u32 = 0;
|
||||
}
|
||||
|
||||
impl pallet_authorship::Config for Runtime {
|
||||
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
|
||||
type UncleGenerations = UncleGenerations;
|
||||
type FilterUncle = ();
|
||||
type EventHandler = (CollatorSelection,);
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||
pub const MaxLocks: u32 = 50;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
type MaxLocks = MaxLocks;
|
||||
/// The type for recording an account's balance.
|
||||
type Balance = Balance;
|
||||
/// The ubiquitous event type.
|
||||
type Event = Event;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
/// Relay Chain `TransactionByteFee` / 10
|
||||
pub const TransactionByteFee: Balance = 1 * MILLICENTS;
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction =
|
||||
pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees<Runtime>>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = WeightToFee;
|
||||
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const AssetDeposit: Balance = 100 * DOLLARS; // 100 DOLLARS deposit to create asset
|
||||
pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||
pub const StringLimit: u32 = 50;
|
||||
/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
|
||||
// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
|
||||
pub const MetadataDepositBase: Balance = deposit(1, 68);
|
||||
pub const MetadataDepositPerByte: Balance = deposit(0, 1);
|
||||
pub const ExecutiveBody: BodyId = BodyId::Executive;
|
||||
}
|
||||
|
||||
/// We allow root and the Relay Chain council to execute privileged asset operations.
|
||||
pub type AssetsForceOrigin = EnsureOneOf<
|
||||
AccountId,
|
||||
EnsureRoot<AccountId>,
|
||||
EnsureXcm<IsMajorityOfBody<DotLocation, ExecutiveBody>>,
|
||||
>;
|
||||
|
||||
impl pallet_assets::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Balance = Balance;
|
||||
type AssetId = u32;
|
||||
type Currency = Balances;
|
||||
type ForceOrigin = AssetsForceOrigin;
|
||||
type AssetDeposit = AssetDeposit;
|
||||
type MetadataDepositBase = MetadataDepositBase;
|
||||
type MetadataDepositPerByte = MetadataDepositPerByte;
|
||||
type ApprovalDeposit = ApprovalDeposit;
|
||||
type StringLimit = StringLimit;
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type WeightInfo = weights::pallet_assets::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
|
||||
pub const DepositBase: Balance = deposit(1, 88);
|
||||
// Additional storage item size of 32 bytes.
|
||||
pub const DepositFactor: Balance = deposit(0, 32);
|
||||
pub const MaxSignatories: u16 = 100;
|
||||
}
|
||||
|
||||
impl pallet_multisig::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type Currency = Balances;
|
||||
type DepositBase = DepositBase;
|
||||
type DepositFactor = DepositFactor;
|
||||
type MaxSignatories = MaxSignatories;
|
||||
type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
impl pallet_utility::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size 32, value size 8; .
|
||||
pub const ProxyDepositBase: Balance = deposit(1, 40);
|
||||
// Additional storage item size of 33 bytes.
|
||||
pub const ProxyDepositFactor: Balance = deposit(0, 33);
|
||||
pub const MaxProxies: u16 = 32;
|
||||
// One storage item; key size 32, value size 16
|
||||
pub const AnnouncementDepositBase: Balance = deposit(1, 48);
|
||||
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 {
|
||||
/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
|
||||
Any,
|
||||
/// Can execute any call that does not transfer funds or assets.
|
||||
NonTransfer,
|
||||
/// Proxy with the ability to reject time-delay proxy announcements.
|
||||
CancelProxy,
|
||||
/// Assets proxy. Can execute any call from `assets`, **including asset transfers**.
|
||||
Assets,
|
||||
/// Owner proxy. Can execute calls related to asset ownership.
|
||||
AssetOwner,
|
||||
/// Asset manager. Can execute calls related to asset management.
|
||||
AssetManager,
|
||||
// Collator selection proxy. Can execute calls related to collator selection mechanism.
|
||||
Collator,
|
||||
}
|
||||
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::Assets(pallet_assets::Call::transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_keep_alive(..)) |
|
||||
Call::Assets(pallet_assets::Call::force_transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::approve_transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_approved(..))
|
||||
),
|
||||
ProxyType::CancelProxy => matches!(c,
|
||||
Call::Proxy(pallet_proxy::Call::reject_announcement(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::Assets => {
|
||||
matches!(c, Call::Assets(..) | Call::Utility(..) | Call::Multisig(..))
|
||||
}
|
||||
ProxyType::AssetOwner => matches!(c,
|
||||
Call::Assets(pallet_assets::Call::create(..)) |
|
||||
Call::Assets(pallet_assets::Call::destroy(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
|
||||
Call::Assets(pallet_assets::Call::set_team(..)) |
|
||||
Call::Assets(pallet_assets::Call::set_metadata(..)) |
|
||||
Call::Assets(pallet_assets::Call::clear_metadata(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::AssetManager => matches!(c,
|
||||
Call::Assets(pallet_assets::Call::mint(..)) |
|
||||
Call::Assets(pallet_assets::Call::burn(..)) |
|
||||
Call::Assets(pallet_assets::Call::freeze(..)) |
|
||||
Call::Assets(pallet_assets::Call::thaw(..)) |
|
||||
Call::Assets(pallet_assets::Call::freeze_asset(..)) |
|
||||
Call::Assets(pallet_assets::Call::thaw_asset(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::Collator => matches!(c,
|
||||
Call::CollatorSelection(..) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
)
|
||||
}
|
||||
}
|
||||
fn is_superset(&self, o: &Self) -> bool {
|
||||
match (self, o) {
|
||||
(x, y) if x == y => true,
|
||||
(ProxyType::Any, _) => true,
|
||||
(_, ProxyType::Any) => false,
|
||||
(ProxyType::Assets, ProxyType::AssetOwner) => true,
|
||||
(ProxyType::Assets, ProxyType::AssetManager) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_proxy::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type Currency = Balances;
|
||||
type ProxyType = ProxyType;
|
||||
type ProxyDepositBase = ProxyDepositBase;
|
||||
type ProxyDepositFactor = ProxyDepositFactor;
|
||||
type MaxProxies = MaxProxies;
|
||||
type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
|
||||
type MaxPending = MaxPending;
|
||||
type CallHasher = BlakeTwo256;
|
||||
type AnnouncementDepositBase = AnnouncementDepositBase;
|
||||
type AnnouncementDepositFactor = AnnouncementDepositFactor;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_parachain_system::Config for Runtime {
|
||||
type Event = Event;
|
||||
type OnValidationData = ();
|
||||
type SelfParaId = parachain_info::Pallet<Runtime>;
|
||||
type DmpMessageHandler = DmpQueue;
|
||||
type ReservedDmpWeight = ReservedDmpWeight;
|
||||
type OutboundXcmpMessageSource = XcmpQueue;
|
||||
type XcmpMessageHandler = XcmpQueue;
|
||||
type ReservedXcmpWeight = ReservedXcmpWeight;
|
||||
}
|
||||
|
||||
impl parachain_info::Config for Runtime {}
|
||||
|
||||
impl cumulus_pallet_aura_ext::Config for Runtime {}
|
||||
|
||||
parameter_types! {
|
||||
pub const DotLocation: MultiLocation = MultiLocation::X1(Junction::Parent);
|
||||
pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
|
||||
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub Ancestry: MultiLocation = Junction::Parachain(ParachainInfo::parachain_id().into()).into();
|
||||
}
|
||||
|
||||
/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
|
||||
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
|
||||
/// `Transact` in order to determine the dispatch Origin.
|
||||
pub type LocationToAccountId = (
|
||||
// The parent (Relay-chain) origin converts to the default `AccountId`.
|
||||
ParentIsDefault<AccountId>,
|
||||
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
|
||||
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
|
||||
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||
);
|
||||
|
||||
/// Means for transacting assets on this chain.
|
||||
pub type LocalAssetTransactor = CurrencyAdapter<
|
||||
// Use this currency:
|
||||
Balances,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
IsConcrete<DotLocation>,
|
||||
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
AccountId,
|
||||
// We don't track any teleports.
|
||||
(),
|
||||
>;
|
||||
|
||||
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
|
||||
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
|
||||
/// biases the kind of local `Origin` it will become.
|
||||
pub type XcmOriginToTransactDispatchOrigin = (
|
||||
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
|
||||
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
|
||||
// foreign chains who want to have a local sovereign account on this chain which they control.
|
||||
SovereignSignedViaLocation<LocationToAccountId, Origin>,
|
||||
// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
|
||||
// recognised.
|
||||
RelayChainAsNative<RelayChainOrigin, Origin>,
|
||||
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
|
||||
// recognised.
|
||||
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
|
||||
// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
|
||||
// transaction from the Root origin.
|
||||
ParentAsSuperuser<Origin>,
|
||||
// Native signed account converter; this just converts an `AccountId32` origin into a normal
|
||||
// `Origin::Signed` origin of the same 32-byte value.
|
||||
SignedAccountId32AsNative<RelayNetwork, Origin>,
|
||||
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
|
||||
XcmPassthrough<Origin>,
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
// One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
|
||||
pub UnitWeightCost: Weight = 1_000_000;
|
||||
}
|
||||
|
||||
match_type! {
|
||||
pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {
|
||||
MultiLocation::X1(Junction::Parent) |
|
||||
MultiLocation::X2(Junction::Parent, Junction::Plurality { id: BodyId::Executive, .. })
|
||||
};
|
||||
}
|
||||
|
||||
pub type Barrier = (
|
||||
TakeWeightCredit,
|
||||
AllowTopLevelPaidExecutionFrom<All<MultiLocation>>,
|
||||
AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
|
||||
// ^^^ Parent and its exec plurality get free execution
|
||||
);
|
||||
|
||||
pub struct XcmConfig;
|
||||
impl Config for XcmConfig {
|
||||
type Call = Call;
|
||||
type XcmSender = XcmRouter;
|
||||
// How to withdraw and deposit an asset.
|
||||
type AssetTransactor = LocalAssetTransactor;
|
||||
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||
type IsReserve = NativeAsset;
|
||||
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of DOT
|
||||
type LocationInverter = LocationInverter<Ancestry>;
|
||||
type Barrier = Barrier;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
|
||||
type Trader = UsingComponents<IdentityFee<Balance>, DotLocation, AccountId, Balances, ()>;
|
||||
type ResponseHandler = (); // Don't handle responses for now.
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
|
||||
}
|
||||
|
||||
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
|
||||
pub type LocalOriginToLocation = (
|
||||
SignedToAccountId32<Origin, AccountId, RelayNetwork>,
|
||||
);
|
||||
|
||||
/// The means for routing XCM messages which are not for local execution into the right message
|
||||
/// queues.
|
||||
pub type XcmRouter = (
|
||||
// Two routers - use UMP to communicate with the relay chain:
|
||||
cumulus_primitives_utility::ParentAsUmp<ParachainSystem>,
|
||||
// ..and XCMP to communicate with the sibling chains.
|
||||
XcmpQueue,
|
||||
);
|
||||
|
||||
impl pallet_xcm::Config for Runtime {
|
||||
type Event = Event;
|
||||
type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||
type XcmRouter = XcmRouter;
|
||||
type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||
type XcmExecuteFilter = All<(MultiLocation, Xcm<Call>)>;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
|
||||
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_xcm::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_xcmp_queue::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type ChannelInfo = ParachainSystem;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_dmp_queue::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33);
|
||||
pub const Period: u32 = 6 * HOURS;
|
||||
pub const Offset: u32 = 0;
|
||||
}
|
||||
|
||||
impl pallet_session::Config for Runtime {
|
||||
type Event = Event;
|
||||
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||
// we don't have stash and controller, thus we don't need the convert as well.
|
||||
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionManager = CollatorSelection;
|
||||
// Essentially just Aura, but lets be pedantic.
|
||||
type SessionHandler = <opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
||||
type Keys = opaque::SessionKeys;
|
||||
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
impl pallet_aura::Config for Runtime {
|
||||
type AuthorityId = AuraId;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const PotId: PalletId = PalletId(*b"PotStake");
|
||||
pub const MaxCandidates: u32 = 1000;
|
||||
pub const SessionLength: BlockNumber = 6 * HOURS;
|
||||
pub const MaxInvulnerables: u32 = 100;
|
||||
}
|
||||
|
||||
/// We allow root and the Relay Chain council to execute privileged collator selection operations.
|
||||
pub type CollatorSelectionUpdateOrigin = EnsureOneOf<
|
||||
AccountId,
|
||||
EnsureRoot<AccountId>,
|
||||
EnsureXcm<IsMajorityOfBody<DotLocation, ExecutiveBody>>,
|
||||
>;
|
||||
|
||||
impl pallet_collator_selection::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Currency = Balances;
|
||||
type UpdateOrigin = CollatorSelectionUpdateOrigin;
|
||||
type PotId = PotId;
|
||||
type MaxCandidates = MaxCandidates;
|
||||
type MaxInvulnerables = MaxInvulnerables;
|
||||
// should be a multiple of session or things will get inconsistent
|
||||
type KickThreshold = Period;
|
||||
type WeightInfo = weights::pallet_collator_selection::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
// Create the runtime by composing the FRAME pallets that were previously configured.
|
||||
construct_runtime!(
|
||||
pub enum Runtime where
|
||||
Block = Block,
|
||||
NodeBlock = opaque::Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
{
|
||||
// System support stuff.
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>} = 0,
|
||||
ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 1,
|
||||
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Call, Storage} = 2,
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
|
||||
ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4,
|
||||
|
||||
// Monetary stuff.
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 10,
|
||||
TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 11,
|
||||
|
||||
// Collator support. the order of these 4 are important and shall not change.
|
||||
Authorship: pallet_authorship::{Pallet, Call, Storage} = 20,
|
||||
CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>, Config<T>} = 21,
|
||||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 22,
|
||||
Aura: pallet_aura::{Pallet, Storage, Config<T>} = 23,
|
||||
AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24,
|
||||
|
||||
// XCM helpers.
|
||||
XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 30,
|
||||
PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 31,
|
||||
CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 32,
|
||||
DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 33,
|
||||
|
||||
// Handy utilities.
|
||||
Utility: pallet_utility::{Pallet, Call, Event} = 40,
|
||||
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 41,
|
||||
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 42,
|
||||
|
||||
// The main stage. To include pallet-assets-freezer and pallet-uniques.
|
||||
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 50,
|
||||
}
|
||||
);
|
||||
|
||||
/// The address format for describing accounts.
|
||||
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
|
||||
/// Block type as expected by this runtime.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// A Block signed with a Justification
|
||||
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
/// BlockId type as expected by this runtime.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
/// The SignedExtension to the basic transaction logic.
|
||||
pub type SignedExtra = (
|
||||
frame_system::CheckSpecVersion<Runtime>,
|
||||
frame_system::CheckTxVersion<Runtime>,
|
||||
frame_system::CheckGenesis<Runtime>,
|
||||
frame_system::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>;
|
||||
/// 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,
|
||||
>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||
fn slot_duration() -> sp_consensus_aura::SlotDuration {
|
||||
sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuraId> {
|
||||
Aura::authorities()
|
||||
}
|
||||
}
|
||||
|
||||
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: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
|
||||
data.create_extrinsics()
|
||||
}
|
||||
|
||||
fn check_inherents(
|
||||
block: Block,
|
||||
data: sp_inherents::InherentData,
|
||||
) -> sp_inherents::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 sp_session::SessionKeys<Block> for Runtime {
|
||||
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
|
||||
opaque::SessionKeys::generate(seed)
|
||||
}
|
||||
|
||||
fn decode_session_keys(
|
||||
encoded: Vec<u8>,
|
||||
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
|
||||
opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
|
||||
fn account_nonce(account: AccountId) -> Index {
|
||||
System::account_nonce(account)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
|
||||
fn query_info(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
|
||||
TransactionPayment::query_info(uxt, len)
|
||||
}
|
||||
fn query_fee_details(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment::FeeDetails<Balance> {
|
||||
TransactionPayment::query_fee_details(uxt, len)
|
||||
}
|
||||
}
|
||||
|
||||
impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
|
||||
fn collect_collation_info() -> cumulus_primitives_core::CollationInfo {
|
||||
ParachainSystem::collect_collation_info()
|
||||
}
|
||||
}
|
||||
|
||||
#[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};
|
||||
|
||||
use frame_system_benchmarking::Pallet as SystemBench;
|
||||
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(),
|
||||
];
|
||||
|
||||
let mut batches = Vec::<BenchmarkBatch>::new();
|
||||
let params = (&config, &whitelist);
|
||||
|
||||
add_benchmark!(params, batches, frame_system, SystemBench::<Runtime>);
|
||||
add_benchmark!(params, batches, pallet_assets, Assets);
|
||||
add_benchmark!(params, batches, pallet_balances, Balances);
|
||||
add_benchmark!(params, batches, pallet_multisig, Multisig);
|
||||
add_benchmark!(params, batches, pallet_proxy, Proxy);
|
||||
add_benchmark!(params, batches, pallet_utility, Utility);
|
||||
add_benchmark!(params, batches, pallet_timestamp, Timestamp);
|
||||
add_benchmark!(params, batches, pallet_collator_selection, CollatorSelection);
|
||||
|
||||
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
|
||||
Ok(batches)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cumulus_pallet_parachain_system::register_validate_block!(
|
||||
Runtime,
|
||||
cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
pub mod pallet_assets;
|
||||
pub mod pallet_balances;
|
||||
pub mod pallet_multisig;
|
||||
pub mod pallet_collator_selection;
|
||||
pub mod pallet_proxy;
|
||||
pub mod pallet_timestamp;
|
||||
pub mod pallet_utility;
|
||||
@@ -0,0 +1,161 @@
|
||||
|
||||
//! Autogenerated weights for pallet_assets
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_assets
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_assets.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_assets::WeightInfo for WeightInfo<T> {
|
||||
fn create() -> Weight {
|
||||
(44_125_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_create() -> Weight {
|
||||
(22_842_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn destroy(c: u32, s: u32, a: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 37_000
|
||||
.saturating_add((21_822_000 as Weight).saturating_mul(c as Weight))
|
||||
// Standard Error: 37_000
|
||||
.saturating_add((29_044_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 370_000
|
||||
.saturating_add((3_000_000 as Weight).saturating_mul(a as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(s as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(s as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(a as Weight)))
|
||||
}
|
||||
fn mint() -> Weight {
|
||||
(49_933_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn burn() -> Weight {
|
||||
(56_434_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn transfer() -> Weight {
|
||||
(85_393_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn transfer_keep_alive() -> Weight {
|
||||
(72_039_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn force_transfer() -> Weight {
|
||||
(85_214_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn freeze() -> Weight {
|
||||
(31_915_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn thaw() -> Weight {
|
||||
(31_296_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn freeze_asset() -> Weight {
|
||||
(22_272_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn thaw_asset() -> Weight {
|
||||
(22_336_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_ownership() -> Weight {
|
||||
(25_526_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_team() -> Weight {
|
||||
(22_632_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_metadata(_n: u32, s: u32, ) -> Weight {
|
||||
(50_330_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((9_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn clear_metadata() -> Weight {
|
||||
(48_266_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_set_metadata(_n: u32, s: u32, ) -> Weight {
|
||||
(26_249_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((6_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_clear_metadata() -> Weight {
|
||||
(49_616_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_asset_status() -> Weight {
|
||||
(22_596_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_transfer() -> Weight {
|
||||
(48_708_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_approved() -> Weight {
|
||||
(108_476_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(5 as Weight))
|
||||
}
|
||||
fn cancel_approval() -> Weight {
|
||||
(49_157_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_cancel_approval() -> Weight {
|
||||
(56_862_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
//! Autogenerated weights for pallet_balances
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_balances
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_balances.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
|
||||
fn transfer() -> Weight {
|
||||
(79_601_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_keep_alive() -> Weight {
|
||||
(58_429_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_balance_creating() -> Weight {
|
||||
(29_124_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_balance_killing() -> Weight {
|
||||
(36_476_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_transfer() -> Weight {
|
||||
(78_772_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
//! Autogenerated weights for pallet_collator_selection
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_collator_selection
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_collator_selection.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_collator_selection::WeightInfo for WeightInfo<T> {
|
||||
fn set_invulnerables(b: u32, ) -> Weight {
|
||||
(18_563_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((68_000 as Weight).saturating_mul(b as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_desired_candidates() -> Weight {
|
||||
(16_363_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_candidacy_bond() -> Weight {
|
||||
(16_840_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn register_as_candidate(c: u32, ) -> Weight {
|
||||
(71_196_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((198_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn leave_intent(c: u32, ) -> Weight {
|
||||
(55_336_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((151_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn note_author() -> Weight {
|
||||
(71_461_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn new_session(r: u32, c: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((109_961_000 as Weight).saturating_mul(r as Weight))
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((151_952_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
//! Autogenerated weights for pallet_multisig
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_multisig
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_multisig.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_multisig::WeightInfo for WeightInfo<T> {
|
||||
fn as_multi_threshold_1(z: u32, ) -> Weight {
|
||||
(14_936_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
}
|
||||
fn as_multi_create(s: u32, z: u32, ) -> Weight {
|
||||
(56_090_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((63_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn as_multi_create_store(s: u32, z: u32, ) -> Weight {
|
||||
(62_519_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((66_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((3_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn as_multi_approve(s: u32, z: u32, ) -> Weight {
|
||||
(30_781_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((111_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn as_multi_approve_store(s: u32, z: u32, ) -> Weight {
|
||||
(60_393_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((118_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((3_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn as_multi_complete(s: u32, z: u32, ) -> Weight {
|
||||
(81_704_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((248_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((5_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn approve_as_multi_create(s: u32, ) -> Weight {
|
||||
(55_585_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((115_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_as_multi_approve(s: u32, ) -> Weight {
|
||||
(33_483_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((82_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_as_multi_complete(s: u32, ) -> Weight {
|
||||
(154_732_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((253_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn cancel_as_multi(s: u32, ) -> Weight {
|
||||
(104_447_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((114_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
//! Autogenerated weights for pallet_proxy
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_proxy
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_proxy.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_proxy::WeightInfo for WeightInfo<T> {
|
||||
fn proxy(p: u32, ) -> Weight {
|
||||
(27_585_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((203_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
}
|
||||
fn proxy_announced(a: u32, p: u32, ) -> Weight {
|
||||
(61_093_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((680_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((201_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn remove_announcement(a: u32, p: u32, ) -> Weight {
|
||||
(39_494_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((686_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((1_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn reject_announcement(a: u32, p: u32, ) -> Weight {
|
||||
(39_817_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((685_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((1_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn announce(a: u32, p: u32, ) -> Weight {
|
||||
(54_835_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((684_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((205_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn add_proxy(p: u32, ) -> Weight {
|
||||
(37_625_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((300_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn remove_proxy(p: u32, ) -> Weight {
|
||||
(36_945_000 as Weight)
|
||||
// Standard Error: 3_000
|
||||
.saturating_add((325_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn remove_proxies(p: u32, ) -> Weight {
|
||||
(35_128_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((209_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn anonymous(p: u32, ) -> Weight {
|
||||
(51_624_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((41_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn kill_anonymous(p: u32, ) -> Weight {
|
||||
(37_469_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((204_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
//! Autogenerated weights for pallet_timestamp
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_timestamp
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_timestamp.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_timestamp::WeightInfo for WeightInfo<T> {
|
||||
fn set() -> Weight {
|
||||
(7_687_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn on_finalize() -> Weight {
|
||||
(4_303_000 as Weight)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
//! Autogenerated weights for pallet_utility
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_utility
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_utility.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
|
||||
fn batch(c: u32, ) -> Weight {
|
||||
(15_408_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((4_571_000 as Weight).saturating_mul(c as Weight))
|
||||
}
|
||||
fn as_derivative() -> Weight {
|
||||
(7_817_000 as Weight)
|
||||
}
|
||||
fn batch_all(c: u32, ) -> Weight {
|
||||
(16_520_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((4_571_000 as Weight).saturating_mul(c as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
[package]
|
||||
name = 'westmint-runtime'
|
||||
version = '1.0.0'
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = '2018'
|
||||
description = "Westend variant of Statemint parachain runtime"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
|
||||
log = { version = "0.4.14", default-features = false }
|
||||
parachain-info = { path = "../pallets/parachain-info", default-features = false }
|
||||
smallvec = "1.6.1"
|
||||
hex-literal = { version = '0.3.1', optional = true }
|
||||
|
||||
# Substrate dependencies
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
frame-benchmarking = { git = "https://github.com/paritytech/substrate", optional = true, default-features = false, branch = "master" }
|
||||
frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", optional = true, default-features = false, branch = "master" }
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-assets = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-authorship = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-multisig = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-proxy = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
pallet-utility = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
node-primitives = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
max-encoded-len = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
# Cumulus dependencies
|
||||
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
|
||||
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
|
||||
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
||||
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
|
||||
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
|
||||
cumulus-pallet-xcm = { path = "../../pallets/xcm", default-features = false }
|
||||
cumulus-ping = { path = "../pallets/ping", default-features = false }
|
||||
pallet-collator-selection = { path = "../../pallets/collator-selection", default-features = false }
|
||||
statemint-common = { path = "../statemint-common", default-features = false }
|
||||
|
||||
# Polkadot dependencies
|
||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.3.1"
|
||||
hex = "0.4.3"
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
runtime-benchmarks = [
|
||||
'hex-literal',
|
||||
'sp-runtime/runtime-benchmarks',
|
||||
'xcm-builder/runtime-benchmarks',
|
||||
'frame-benchmarking',
|
||||
'frame-system-benchmarking',
|
||||
'frame-support/runtime-benchmarks',
|
||||
'frame-system/runtime-benchmarks',
|
||||
'pallet-assets/runtime-benchmarks',
|
||||
'pallet-balances/runtime-benchmarks',
|
||||
'pallet-multisig/runtime-benchmarks',
|
||||
'pallet-proxy/runtime-benchmarks',
|
||||
'pallet-utility/runtime-benchmarks',
|
||||
'pallet-timestamp/runtime-benchmarks',
|
||||
'pallet-xcm/runtime-benchmarks',
|
||||
'pallet-collator-selection/runtime-benchmarks',
|
||||
]
|
||||
std = [
|
||||
"codec/std",
|
||||
"serde",
|
||||
"log/std",
|
||||
"sp-api/std",
|
||||
"sp-std/std",
|
||||
"sp-io/std",
|
||||
"sp-core/std",
|
||||
"sp-runtime/std",
|
||||
"sp-version/std",
|
||||
"sp-offchain/std",
|
||||
"sp-session/std",
|
||||
"sp-block-builder/std",
|
||||
"sp-transaction-pool/std",
|
||||
"sp-inherents/std",
|
||||
"frame-support/std",
|
||||
"frame-executive/std",
|
||||
"frame-system/std",
|
||||
"frame-system-rpc-runtime-api/std",
|
||||
"pallet-assets/std",
|
||||
"pallet-authorship/std",
|
||||
"pallet-aura/std",
|
||||
"pallet-balances/std",
|
||||
"pallet-multisig/std",
|
||||
"pallet-proxy/std",
|
||||
"pallet-randomness-collective-flip/std",
|
||||
"pallet-session/std",
|
||||
"pallet-sudo/std",
|
||||
"pallet-timestamp/std",
|
||||
"pallet-transaction-payment/std",
|
||||
"pallet-transaction-payment-rpc-runtime-api/std",
|
||||
"pallet-utility/std",
|
||||
"parachain-info/std",
|
||||
"cumulus-pallet-aura-ext/std",
|
||||
"pallet-collator-selection/std",
|
||||
"cumulus-pallet-dmp-queue/std",
|
||||
"cumulus-pallet-parachain-system/std",
|
||||
"cumulus-pallet-xcmp-queue/std",
|
||||
"cumulus-pallet-xcm/std",
|
||||
"cumulus-primitives-core/std",
|
||||
"cumulus-primitives-utility/std",
|
||||
"cumulus-ping/std",
|
||||
"xcm/std",
|
||||
"xcm-builder/std",
|
||||
"xcm-executor/std",
|
||||
"sp-consensus-aura/std",
|
||||
"node-primitives/std",
|
||||
"statemint-common/std",
|
||||
]
|
||||
@@ -0,0 +1,9 @@
|
||||
use substrate_wasm_builder::WasmBuilder;
|
||||
|
||||
fn main() {
|
||||
WasmBuilder::new()
|
||||
.with_current_project()
|
||||
.export_heap_base()
|
||||
.import_memory()
|
||||
.build()
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub mod currency {
|
||||
use node_primitives::Balance;
|
||||
|
||||
/// The existential deposit. Set to 1/10 of its parent Relay Chain.
|
||||
pub const EXISTENTIAL_DEPOSIT: Balance = 100 * MILLICENTS;
|
||||
|
||||
pub const UNITS: Balance = 1_000_000_000_000;
|
||||
pub const CENTS: Balance = UNITS / 100;
|
||||
pub const MILLICENTS: Balance = CENTS / 1_000;
|
||||
pub const GRAND: Balance = CENTS * 100_000;
|
||||
|
||||
pub const fn deposit(items: u32, bytes: u32) -> Balance {
|
||||
// 1/10 of Westend testnet
|
||||
(items as Balance * 100 * CENTS + (bytes as Balance) * 5 * MILLICENTS) / 10
|
||||
}
|
||||
}
|
||||
|
||||
/// Fee-related.
|
||||
pub mod fee {
|
||||
use node_primitives::Balance;
|
||||
pub use sp_runtime::Perbill;
|
||||
use frame_support::weights::{
|
||||
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
|
||||
WeightToFeePolynomial,
|
||||
};
|
||||
use smallvec::smallvec;
|
||||
|
||||
/// The block saturation level. Fees will be updates based on this value.
|
||||
pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
|
||||
|
||||
/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
|
||||
/// node's balance type.
|
||||
///
|
||||
/// This should typically create a mapping between the following ranges:
|
||||
/// - [0, MAXIMUM_BLOCK_WEIGHT]
|
||||
/// - [Balance::min, Balance::max]
|
||||
///
|
||||
/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
|
||||
/// - Setting it to `0` will essentially disable the weight fee.
|
||||
/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
|
||||
pub struct WeightToFee;
|
||||
impl WeightToFeePolynomial for WeightToFee {
|
||||
type Balance = Balance;
|
||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||
// in Statemint, we map to 1/10 of that, or 1/100 CENT
|
||||
let p = super::currency::CENTS;
|
||||
let q = 100 * Balance::from(ExtrinsicBaseWeight::get());
|
||||
smallvec![WeightToFeeCoefficient {
|
||||
degree: 1,
|
||||
negative: false,
|
||||
coeff_frac: Perbill::from_rational(p % q, q),
|
||||
coeff_integer: p / q,
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,816 @@
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Westmint runtime.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
// Make the WASM binary available.
|
||||
#[cfg(feature = "std")]
|
||||
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
|
||||
pub mod constants;
|
||||
mod weights;
|
||||
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||
use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT};
|
||||
use sp_runtime::{
|
||||
create_runtime_str, generic, impl_opaque_keys,
|
||||
transaction_validity::{TransactionSource, TransactionValidity},
|
||||
ApplyExtrinsicResult,
|
||||
};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_version::NativeVersion;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
use frame_system::{
|
||||
EnsureRoot, limits::{BlockLength, BlockWeights},
|
||||
};
|
||||
use statemint_common::{
|
||||
BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId, Header,
|
||||
NORMAL_DISPATCH_RATIO, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, SLOT_DURATION, HOURS,
|
||||
};
|
||||
pub use statemint_common as common;
|
||||
use statemint_common::impls::DealWithFees;
|
||||
use codec::{Decode, Encode};
|
||||
use constants::{currency::*, fee::WeightToFee};
|
||||
use frame_support::{
|
||||
construct_runtime, parameter_types, match_type,
|
||||
traits::{InstanceFilter, All, MaxEncodedLen},
|
||||
weights::{
|
||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
|
||||
DispatchClass, IdentityFee, Weight,
|
||||
},
|
||||
RuntimeDebug, PalletId,
|
||||
};
|
||||
use sp_runtime::Perbill;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
|
||||
// Polkadot imports
|
||||
use polkadot_parachain::primitives::Sibling;
|
||||
use polkadot_runtime_common::{
|
||||
BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate,
|
||||
};
|
||||
use xcm::v0::{MultiAsset, Junction, MultiLocation, NetworkId, Xcm};
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
|
||||
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
|
||||
SovereignSignedViaLocation, EnsureXcmOrigin,
|
||||
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
|
||||
AllowUnpaidExecutionFrom, ParentAsSuperuser, SignedToAccountId32, UsingComponents,
|
||||
};
|
||||
use xcm_executor::{Config, XcmExecutor};
|
||||
use pallet_xcm::XcmPassthrough;
|
||||
|
||||
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
|
||||
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
|
||||
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
|
||||
/// to even the core data structures.
|
||||
pub mod opaque {
|
||||
use super::*;
|
||||
pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
|
||||
|
||||
/// Opaque block type.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
|
||||
pub type SessionHandlers = ();
|
||||
|
||||
impl_opaque_keys! {
|
||||
pub struct SessionKeys {
|
||||
pub aura: Aura,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[sp_version::runtime_version]
|
||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("westmint"),
|
||||
impl_name: create_runtime_str!("westmint"),
|
||||
authoring_version: 1,
|
||||
spec_version: 1,
|
||||
impl_version: 1,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
};
|
||||
|
||||
/// The version information used to identify this runtime when compiled natively.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn native_version() -> NativeVersion {
|
||||
NativeVersion {
|
||||
runtime_version: VERSION,
|
||||
can_author_with: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
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;
|
||||
}
|
||||
|
||||
// Configure FRAME pallets to include in runtime.
|
||||
|
||||
impl frame_system::Config for Runtime {
|
||||
type BaseCallFilter = ();
|
||||
type BlockWeights = RuntimeBlockWeights;
|
||||
type BlockLength = RuntimeBlockLength;
|
||||
type AccountId = AccountId;
|
||||
type Call = Call;
|
||||
type Lookup = AccountIdLookup<AccountId, ()>;
|
||||
type Index = Index;
|
||||
type BlockNumber = BlockNumber;
|
||||
type Hash = Hash;
|
||||
type Hashing = BlakeTwo256;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type Origin = Origin;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type DbWeight = RocksDbWeight;
|
||||
type Version = Version;
|
||||
type PalletInfo = PalletInfo;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type AccountData = pallet_balances::AccountData<Balance>;
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
||||
}
|
||||
|
||||
impl pallet_timestamp::Config for Runtime {
|
||||
/// A timestamp: milliseconds since the unix epoch.
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = ();
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const UncleGenerations: u32 = 0;
|
||||
}
|
||||
|
||||
impl pallet_authorship::Config for Runtime {
|
||||
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
|
||||
type UncleGenerations = UncleGenerations;
|
||||
type FilterUncle = ();
|
||||
type EventHandler = (CollatorSelection,);
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||
pub const MaxLocks: u32 = 50;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
type MaxLocks = MaxLocks;
|
||||
/// The type for recording an account's balance.
|
||||
type Balance = Balance;
|
||||
/// The ubiquitous event type.
|
||||
type Event = Event;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
/// Relay Chain `TransactionByteFee` / 10
|
||||
pub const TransactionByteFee: Balance = 1 * MILLICENTS;
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction =
|
||||
pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees<Runtime>>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = WeightToFee;
|
||||
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
|
||||
}
|
||||
|
||||
impl pallet_sudo::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const AssetDeposit: Balance = 100 * UNITS; // 100 WND deposit to create asset
|
||||
pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||
pub const StringLimit: u32 = 50;
|
||||
/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
|
||||
// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
|
||||
pub const MetadataDepositBase: Balance = deposit(1, 68);
|
||||
pub const MetadataDepositPerByte: Balance = deposit(0, 1);
|
||||
}
|
||||
|
||||
impl pallet_assets::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Balance = Balance;
|
||||
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 = weights::pallet_assets::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
|
||||
pub const DepositBase: Balance = deposit(1, 88);
|
||||
// Additional storage item size of 32 bytes.
|
||||
pub const DepositFactor: Balance = deposit(0, 32);
|
||||
pub const MaxSignatories: u16 = 100;
|
||||
}
|
||||
|
||||
impl pallet_multisig::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type Currency = Balances;
|
||||
type DepositBase = DepositBase;
|
||||
type DepositFactor = DepositFactor;
|
||||
type MaxSignatories = MaxSignatories;
|
||||
type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
impl pallet_utility::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size 32, value size 8; .
|
||||
pub const ProxyDepositBase: Balance = deposit(1, 40);
|
||||
// Additional storage item size of 33 bytes.
|
||||
pub const ProxyDepositFactor: Balance = deposit(0, 33);
|
||||
pub const MaxProxies: u16 = 32;
|
||||
// One storage item; key size 32, value size 16
|
||||
pub const AnnouncementDepositBase: Balance = deposit(1, 48);
|
||||
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 {
|
||||
/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
|
||||
Any,
|
||||
/// Can execute any call that does not transfer funds, including asset transfers.
|
||||
NonTransfer,
|
||||
/// Proxy with the ability to reject time-delay proxy announcements.
|
||||
CancelProxy,
|
||||
/// Assets proxy. Can execute any call from `assets`, **including asset transfers**.
|
||||
Assets,
|
||||
/// Owner proxy. Can execute calls related to asset ownership.
|
||||
AssetOwner,
|
||||
/// Asset manager. Can execute calls related to asset management.
|
||||
AssetManager,
|
||||
// Collator selection proxy. Can execute calls related to collator selection mechanism.
|
||||
Collator,
|
||||
}
|
||||
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::Assets(pallet_assets::Call::transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_keep_alive(..)) |
|
||||
Call::Assets(pallet_assets::Call::force_transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::approve_transfer(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_approved(..))
|
||||
),
|
||||
ProxyType::CancelProxy => matches!(c,
|
||||
Call::Proxy(pallet_proxy::Call::reject_announcement(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::Assets => {
|
||||
matches!(c, Call::Assets(..) | Call::Utility(..) | Call::Multisig(..))
|
||||
}
|
||||
ProxyType::AssetOwner => matches!(c,
|
||||
Call::Assets(pallet_assets::Call::create(..)) |
|
||||
Call::Assets(pallet_assets::Call::destroy(..)) |
|
||||
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
|
||||
Call::Assets(pallet_assets::Call::set_team(..)) |
|
||||
Call::Assets(pallet_assets::Call::set_metadata(..)) |
|
||||
Call::Assets(pallet_assets::Call::clear_metadata(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::AssetManager => matches!(c,
|
||||
Call::Assets(pallet_assets::Call::mint(..)) |
|
||||
Call::Assets(pallet_assets::Call::burn(..)) |
|
||||
Call::Assets(pallet_assets::Call::freeze(..)) |
|
||||
Call::Assets(pallet_assets::Call::thaw(..)) |
|
||||
Call::Assets(pallet_assets::Call::freeze_asset(..)) |
|
||||
Call::Assets(pallet_assets::Call::thaw_asset(..)) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
),
|
||||
ProxyType::Collator => matches!(c,
|
||||
Call::CollatorSelection(..) |
|
||||
Call::Utility(..) |
|
||||
Call::Multisig(..)
|
||||
)
|
||||
}
|
||||
}
|
||||
fn is_superset(&self, o: &Self) -> bool {
|
||||
match (self, o) {
|
||||
(x, y) if x == y => true,
|
||||
(ProxyType::Any, _) => true,
|
||||
(_, ProxyType::Any) => false,
|
||||
(ProxyType::Assets, ProxyType::AssetOwner) => true,
|
||||
(ProxyType::Assets, ProxyType::AssetManager) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_proxy::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Call = Call;
|
||||
type Currency = Balances;
|
||||
type ProxyType = ProxyType;
|
||||
type ProxyDepositBase = ProxyDepositBase;
|
||||
type ProxyDepositFactor = ProxyDepositFactor;
|
||||
type MaxProxies = MaxProxies;
|
||||
type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
|
||||
type MaxPending = MaxPending;
|
||||
type CallHasher = BlakeTwo256;
|
||||
type AnnouncementDepositBase = AnnouncementDepositBase;
|
||||
type AnnouncementDepositFactor = AnnouncementDepositFactor;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_parachain_system::Config for Runtime {
|
||||
type Event = Event;
|
||||
type OnValidationData = ();
|
||||
type SelfParaId = parachain_info::Pallet<Runtime>;
|
||||
type DmpMessageHandler = DmpQueue;
|
||||
type ReservedDmpWeight = ReservedDmpWeight;
|
||||
type OutboundXcmpMessageSource = XcmpQueue;
|
||||
type XcmpMessageHandler = XcmpQueue;
|
||||
type ReservedXcmpWeight = ReservedXcmpWeight;
|
||||
}
|
||||
|
||||
impl parachain_info::Config for Runtime {}
|
||||
|
||||
impl cumulus_pallet_aura_ext::Config for Runtime {}
|
||||
|
||||
parameter_types! {
|
||||
pub const WestendLocation: MultiLocation = MultiLocation::X1(Junction::Parent);
|
||||
pub RelayNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
|
||||
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub Ancestry: MultiLocation = Junction::Parachain(ParachainInfo::parachain_id().into()).into();
|
||||
}
|
||||
|
||||
/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
|
||||
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
|
||||
/// `Transact` in order to determine the dispatch Origin.
|
||||
pub type LocationToAccountId = (
|
||||
// The parent (Relay-chain) origin converts to the default `AccountId`.
|
||||
ParentIsDefault<AccountId>,
|
||||
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
|
||||
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
|
||||
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||
);
|
||||
|
||||
/// Means for transacting assets on this chain.
|
||||
pub type LocalAssetTransactor = CurrencyAdapter<
|
||||
// Use this currency:
|
||||
Balances,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
IsConcrete<WestendLocation>,
|
||||
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
AccountId,
|
||||
// We don't track any teleports.
|
||||
(),
|
||||
>;
|
||||
|
||||
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
|
||||
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
|
||||
/// biases the kind of local `Origin` it will become.
|
||||
pub type XcmOriginToTransactDispatchOrigin = (
|
||||
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
|
||||
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
|
||||
// foreign chains who want to have a local sovereign account on this chain which they control.
|
||||
SovereignSignedViaLocation<LocationToAccountId, Origin>,
|
||||
// Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when
|
||||
// recognised.
|
||||
RelayChainAsNative<RelayChainOrigin, Origin>,
|
||||
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
|
||||
// recognised.
|
||||
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
|
||||
// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
|
||||
// transaction from the Root origin.
|
||||
ParentAsSuperuser<Origin>,
|
||||
// Native signed account converter; this just converts an `AccountId32` origin into a normal
|
||||
// `Origin::Signed` origin of the same 32-byte value.
|
||||
SignedAccountId32AsNative<RelayNetwork, Origin>,
|
||||
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
|
||||
XcmPassthrough<Origin>,
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub UnitWeightCost: Weight = 1_000;
|
||||
}
|
||||
|
||||
match_type! {
|
||||
pub type ParentOrParentsPlurality: impl Contains<MultiLocation> = {
|
||||
MultiLocation::X1(Junction::Parent) |
|
||||
MultiLocation::X2(Junction::Parent, Junction::Plurality { .. })
|
||||
};
|
||||
}
|
||||
|
||||
pub type Barrier = (
|
||||
TakeWeightCredit,
|
||||
AllowTopLevelPaidExecutionFrom<All<MultiLocation>>,
|
||||
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
|
||||
// ^^^ Parent & its plurality gets free execution
|
||||
);
|
||||
|
||||
pub struct XcmConfig;
|
||||
impl Config for XcmConfig {
|
||||
type Call = Call;
|
||||
type XcmSender = XcmRouter;
|
||||
// How to withdraw and deposit an asset.
|
||||
type AssetTransactor = LocalAssetTransactor;
|
||||
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||
type IsReserve = NativeAsset;
|
||||
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of WND
|
||||
type LocationInverter = LocationInverter<Ancestry>;
|
||||
type Barrier = Barrier;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
|
||||
type Trader = UsingComponents<IdentityFee<Balance>, WestendLocation, AccountId, Balances, ()>;
|
||||
type ResponseHandler = (); // Don't handle responses for now.
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
|
||||
}
|
||||
|
||||
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
|
||||
pub type LocalOriginToLocation = (
|
||||
SignedToAccountId32<Origin, AccountId, RelayNetwork>,
|
||||
);
|
||||
|
||||
/// The means for routing XCM messages which are not for local execution into the right message
|
||||
/// queues.
|
||||
pub type XcmRouter = (
|
||||
// Two routers - use UMP to communicate with the relay chain:
|
||||
cumulus_primitives_utility::ParentAsUmp<ParachainSystem>,
|
||||
// ..and XCMP to communicate with the sibling chains.
|
||||
XcmpQueue,
|
||||
);
|
||||
|
||||
impl pallet_xcm::Config for Runtime {
|
||||
type Event = Event;
|
||||
type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||
type XcmRouter = XcmRouter;
|
||||
type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||
type XcmExecuteFilter = All<(MultiLocation, Xcm<Call>)>;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
|
||||
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_xcm::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_xcmp_queue::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type ChannelInfo = ParachainSystem;
|
||||
}
|
||||
|
||||
impl cumulus_pallet_dmp_queue::Config for Runtime {
|
||||
type Event = Event;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33);
|
||||
pub const Period: u32 = 6 * HOURS;
|
||||
pub const Offset: u32 = 0;
|
||||
}
|
||||
|
||||
impl pallet_session::Config for Runtime {
|
||||
type Event = Event;
|
||||
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||
// we don't have stash and controller, thus we don't need the convert as well.
|
||||
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionManager = CollatorSelection;
|
||||
// Essentially just Aura, but lets be pedantic.
|
||||
type SessionHandler = <opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
||||
type Keys = opaque::SessionKeys;
|
||||
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
impl pallet_aura::Config for Runtime {
|
||||
type AuthorityId = AuraId;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const PotId: PalletId = PalletId(*b"PotStake");
|
||||
pub const MaxCandidates: u32 = 1000;
|
||||
pub const SessionLength: BlockNumber = 6 * HOURS;
|
||||
pub const MaxInvulnerables: u32 = 100;
|
||||
}
|
||||
|
||||
impl pallet_collator_selection::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Currency = Balances;
|
||||
type UpdateOrigin = EnsureRoot<AccountId>;
|
||||
type PotId = PotId;
|
||||
type MaxCandidates = MaxCandidates;
|
||||
type MaxInvulnerables = MaxInvulnerables;
|
||||
// should be a multiple of session or things will get inconsistent
|
||||
type KickThreshold = Period;
|
||||
type WeightInfo = weights::pallet_collator_selection::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
// Create the runtime by composing the FRAME pallets that were previously configured.
|
||||
construct_runtime!(
|
||||
pub enum Runtime where
|
||||
Block = Block,
|
||||
NodeBlock = opaque::Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
{
|
||||
// System support stuff;
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||
ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>},
|
||||
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Call, Storage},
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
|
||||
ParachainInfo: parachain_info::{Pallet, Storage, Config},
|
||||
Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>},
|
||||
|
||||
// Monetary stuff;
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
|
||||
|
||||
// Collator support. the order of these 4 are important and shall not change.
|
||||
Authorship: pallet_authorship::{Pallet, Call, Storage},
|
||||
CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>, Config<T>},
|
||||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
|
||||
Aura: pallet_aura::{Pallet, Storage, Config<T>},
|
||||
AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config},
|
||||
|
||||
// The main stage.
|
||||
Utility: pallet_utility::{Pallet, Call, Event},
|
||||
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>},
|
||||
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>},
|
||||
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>},
|
||||
|
||||
// XCM helpers.
|
||||
XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>},
|
||||
PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin},
|
||||
CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin},
|
||||
DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>},
|
||||
}
|
||||
);
|
||||
|
||||
/// The address format for describing accounts.
|
||||
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
|
||||
/// Block type as expected by this runtime.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// A Block signed with a Justification
|
||||
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
/// BlockId type as expected by this runtime.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
/// The SignedExtension to the basic transaction logic.
|
||||
pub type SignedExtra = (
|
||||
frame_system::CheckSpecVersion<Runtime>,
|
||||
frame_system::CheckTxVersion<Runtime>,
|
||||
frame_system::CheckGenesis<Runtime>,
|
||||
frame_system::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>;
|
||||
/// 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,
|
||||
>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||
fn slot_duration() -> sp_consensus_aura::SlotDuration {
|
||||
sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuraId> {
|
||||
Aura::authorities()
|
||||
}
|
||||
}
|
||||
|
||||
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: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
|
||||
data.create_extrinsics()
|
||||
}
|
||||
|
||||
fn check_inherents(
|
||||
block: Block,
|
||||
data: sp_inherents::InherentData,
|
||||
) -> sp_inherents::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 sp_session::SessionKeys<Block> for Runtime {
|
||||
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
|
||||
opaque::SessionKeys::generate(seed)
|
||||
}
|
||||
|
||||
fn decode_session_keys(
|
||||
encoded: Vec<u8>,
|
||||
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
|
||||
opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
|
||||
fn account_nonce(account: AccountId) -> Index {
|
||||
System::account_nonce(account)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
|
||||
fn query_info(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
|
||||
TransactionPayment::query_info(uxt, len)
|
||||
}
|
||||
fn query_fee_details(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment::FeeDetails<Balance> {
|
||||
TransactionPayment::query_fee_details(uxt, len)
|
||||
}
|
||||
}
|
||||
|
||||
impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
|
||||
fn collect_collation_info() -> cumulus_primitives_core::CollationInfo {
|
||||
ParachainSystem::collect_collation_info()
|
||||
}
|
||||
}
|
||||
|
||||
#[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};
|
||||
|
||||
use frame_system_benchmarking::Pallet as SystemBench;
|
||||
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(),
|
||||
];
|
||||
|
||||
let mut batches = Vec::<BenchmarkBatch>::new();
|
||||
let params = (&config, &whitelist);
|
||||
|
||||
add_benchmark!(params, batches, frame_system, SystemBench::<Runtime>);
|
||||
add_benchmark!(params, batches, pallet_assets, Assets);
|
||||
add_benchmark!(params, batches, pallet_balances, Balances);
|
||||
add_benchmark!(params, batches, pallet_multisig, Multisig);
|
||||
add_benchmark!(params, batches, pallet_proxy, Proxy);
|
||||
add_benchmark!(params, batches, pallet_utility, Utility);
|
||||
add_benchmark!(params, batches, pallet_timestamp, Timestamp);
|
||||
add_benchmark!(params, batches, pallet_collator_selection, CollatorSelection);
|
||||
|
||||
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
|
||||
Ok(batches)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cumulus_pallet_parachain_system::register_validate_block!(
|
||||
Runtime,
|
||||
cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
pub mod pallet_assets;
|
||||
pub mod pallet_balances;
|
||||
pub mod pallet_multisig;
|
||||
pub mod pallet_collator_selection;
|
||||
pub mod pallet_proxy;
|
||||
pub mod pallet_timestamp;
|
||||
pub mod pallet_utility;
|
||||
@@ -0,0 +1,161 @@
|
||||
|
||||
//! Autogenerated weights for pallet_assets
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_assets
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_assets.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_assets::WeightInfo for WeightInfo<T> {
|
||||
fn create() -> Weight {
|
||||
(44_125_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_create() -> Weight {
|
||||
(22_842_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn destroy(c: u32, s: u32, a: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 37_000
|
||||
.saturating_add((21_822_000 as Weight).saturating_mul(c as Weight))
|
||||
// Standard Error: 37_000
|
||||
.saturating_add((29_044_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 370_000
|
||||
.saturating_add((3_000_000 as Weight).saturating_mul(a as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(s as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(s as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(a as Weight)))
|
||||
}
|
||||
fn mint() -> Weight {
|
||||
(49_933_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn burn() -> Weight {
|
||||
(56_434_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn transfer() -> Weight {
|
||||
(85_393_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn transfer_keep_alive() -> Weight {
|
||||
(72_039_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn force_transfer() -> Weight {
|
||||
(85_214_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn freeze() -> Weight {
|
||||
(31_915_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn thaw() -> Weight {
|
||||
(31_296_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn freeze_asset() -> Weight {
|
||||
(22_272_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn thaw_asset() -> Weight {
|
||||
(22_336_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_ownership() -> Weight {
|
||||
(25_526_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_team() -> Weight {
|
||||
(22_632_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_metadata(_n: u32, s: u32, ) -> Weight {
|
||||
(50_330_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((9_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn clear_metadata() -> Weight {
|
||||
(48_266_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_set_metadata(_n: u32, s: u32, ) -> Weight {
|
||||
(26_249_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((6_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_clear_metadata() -> Weight {
|
||||
(49_616_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_asset_status() -> Weight {
|
||||
(22_596_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_transfer() -> Weight {
|
||||
(48_708_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_approved() -> Weight {
|
||||
(108_476_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(5 as Weight))
|
||||
}
|
||||
fn cancel_approval() -> Weight {
|
||||
(49_157_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_cancel_approval() -> Weight {
|
||||
(56_862_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
//! Autogenerated weights for pallet_balances
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_balances
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_balances.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
|
||||
fn transfer() -> Weight {
|
||||
(79_601_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn transfer_keep_alive() -> Weight {
|
||||
(58_429_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_balance_creating() -> Weight {
|
||||
(29_124_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_balance_killing() -> Weight {
|
||||
(36_476_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_transfer() -> Weight {
|
||||
(78_772_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
//! Autogenerated weights for pallet_collator_selection
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_collator_selection
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_collator_selection.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_collator_selection::WeightInfo for WeightInfo<T> {
|
||||
fn set_invulnerables(b: u32, ) -> Weight {
|
||||
(18_563_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((68_000 as Weight).saturating_mul(b as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_desired_candidates() -> Weight {
|
||||
(16_363_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_candidacy_bond() -> Weight {
|
||||
(16_840_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn register_as_candidate(c: u32, ) -> Weight {
|
||||
(71_196_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((198_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn leave_intent(c: u32, ) -> Weight {
|
||||
(55_336_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((151_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn note_author() -> Weight {
|
||||
(71_461_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn new_session(r: u32, c: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((109_961_000 as Weight).saturating_mul(r as Weight))
|
||||
// Standard Error: 1_010_000
|
||||
.saturating_add((151_952_000 as Weight).saturating_mul(c as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(c as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(r as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(c as Weight)))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
//! Autogenerated weights for pallet_multisig
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_multisig
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_multisig.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_multisig::WeightInfo for WeightInfo<T> {
|
||||
fn as_multi_threshold_1(z: u32, ) -> Weight {
|
||||
(14_936_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
}
|
||||
fn as_multi_create(s: u32, z: u32, ) -> Weight {
|
||||
(56_090_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((63_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn as_multi_create_store(s: u32, z: u32, ) -> Weight {
|
||||
(62_519_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((66_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((3_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn as_multi_approve(s: u32, z: u32, ) -> Weight {
|
||||
(30_781_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((111_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((1_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn as_multi_approve_store(s: u32, z: u32, ) -> Weight {
|
||||
(60_393_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((118_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((3_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn as_multi_complete(s: u32, z: u32, ) -> Weight {
|
||||
(81_704_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((248_000 as Weight).saturating_mul(s as Weight))
|
||||
// Standard Error: 0
|
||||
.saturating_add((5_000 as Weight).saturating_mul(z as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn approve_as_multi_create(s: u32, ) -> Weight {
|
||||
(55_585_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((115_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_as_multi_approve(s: u32, ) -> Weight {
|
||||
(33_483_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((82_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn approve_as_multi_complete(s: u32, ) -> Weight {
|
||||
(154_732_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((253_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn cancel_as_multi(s: u32, ) -> Weight {
|
||||
(104_447_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((114_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
//! Autogenerated weights for pallet_proxy
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_proxy
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_proxy.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_proxy::WeightInfo for WeightInfo<T> {
|
||||
fn proxy(p: u32, ) -> Weight {
|
||||
(27_585_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((203_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
}
|
||||
fn proxy_announced(a: u32, p: u32, ) -> Weight {
|
||||
(61_093_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((680_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((201_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn remove_announcement(a: u32, p: u32, ) -> Weight {
|
||||
(39_494_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((686_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((1_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn reject_announcement(a: u32, p: u32, ) -> Weight {
|
||||
(39_817_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((685_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((1_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn announce(a: u32, p: u32, ) -> Weight {
|
||||
(54_835_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((684_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((205_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn add_proxy(p: u32, ) -> Weight {
|
||||
(37_625_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((300_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn remove_proxy(p: u32, ) -> Weight {
|
||||
(36_945_000 as Weight)
|
||||
// Standard Error: 3_000
|
||||
.saturating_add((325_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn remove_proxies(p: u32, ) -> Weight {
|
||||
(35_128_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((209_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn anonymous(p: u32, ) -> Weight {
|
||||
(51_624_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((41_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn kill_anonymous(p: u32, ) -> Weight {
|
||||
(37_469_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((204_000 as Weight).saturating_mul(p as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
//! Autogenerated weights for pallet_timestamp
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_timestamp
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_timestamp.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_timestamp::WeightInfo for WeightInfo<T> {
|
||||
fn set() -> Weight {
|
||||
(7_687_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn on_finalize() -> Weight {
|
||||
(4_303_000 as Weight)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
//! Autogenerated weights for pallet_utility
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-05-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("statemint-dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/statemint
|
||||
// benchmark
|
||||
// --chain=statemint-dev
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_utility
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --raw
|
||||
// --output=./runtime/statemint/src/weights/
|
||||
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions for pallet_utility.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
|
||||
fn batch(c: u32, ) -> Weight {
|
||||
(15_408_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((4_571_000 as Weight).saturating_mul(c as Weight))
|
||||
}
|
||||
fn as_derivative() -> Weight {
|
||||
(7_817_000 as Weight)
|
||||
}
|
||||
fn batch_all(c: u32, ) -> Weight {
|
||||
(16_520_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((4_571_000 as Weight).saturating_mul(c as Weight))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user