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:
Gavin Wood
2021-06-01 20:31:03 +01:00
committed by GitHub
parent 540e74d33c
commit 9d9ed1bc84
54 changed files with 8419 additions and 227 deletions
Generated
+502 -160
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -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",
+57
View File
@@ -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',
]
+1
View File
@@ -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,);
+437
View File
@@ -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.
}
}
}
+241
View File
@@ -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);
}
}
+337
View File
@@ -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();
}
+131
View File
@@ -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)))
}
}
+18
View File
@@ -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',
]
File diff suppressed because one or more lines are too long
+533 -2
View File
@@ -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(),
}
}
+4
View File
@@ -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
+154 -28
View File
@@ -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)
+447 -37
View File
@@ -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))
}
}