Newer
Older
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! The Rococo runtime for v1 parachains.
#![cfg_attr(not(feature = "std"), no_std)]
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use beefy_primitives::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion};
traits::{All, Filter, IsInVec, KeyOwnerProofSystem, OnRuntimeUpgrade, Randomness},
PalletId,
};
use frame_system::EnsureRoot;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use pallet_mmr_primitives as mmr;
use pallet_session::historical as session_historical;
use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use primitives::v1::{
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
CoreState, GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage, Moment,
Nonce, OccupiedCoreAssumption, PersistedValidationData, SessionInfo as SessionInfoData,
Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
};
use runtime_common::{
auctions, crowdloan, impls::ToAuthor, paras_registrar, paras_sudo_wrapper, slots, xcm_sender,
BlockHashCount, BlockLength, BlockWeights, RocksDbWeight, SlowAdjustingFeeUpdate,
use runtime_parachains::{self, runtime_api_impl::v1 as runtime_api_impl};
use sp_core::{OpaqueMetadata, RuntimeDebug};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{
self, AccountIdLookup, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, Keccak256,
OpaqueKeys, SaturatedConversion, Verify,
transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
ApplyExtrinsicResult, KeyTypeId, Perbill,
use sp_staking::SessionIndex;
use sp_std::{collections::btree_map::BTreeMap, prelude::*};
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use runtime_parachains::{
configuration as parachains_configuration, dmp as parachains_dmp, hrmp as parachains_hrmp,
inclusion as parachains_inclusion, initializer as parachains_initializer,
origin as parachains_origin, paras as parachains_paras,
paras_inherent as parachains_paras_inherent, scheduler as parachains_scheduler,
session_info as parachains_session_info, shared as parachains_shared, ump as parachains_ump,
};
use bridge_runtime_common::messages::{
source::estimate_message_dispatch_and_delivery_fee, MessageBridge,
};
pub use pallet_balances::Call as BalancesCall;
use constants::{currency::*, fee::*, time::*};
use frame_support::traits::InstanceFilter;
use xcm::v0::{BodyId, MultiLocation, NetworkId, Xcm};
use xcm_builder::{
AccountId32Aliases, BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia,
ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds,
IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, UsingComponents,
/// Constant values used within the runtime.
pub mod constants;
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
/// Runtime version (Rococo).
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("rococo"),
impl_name: create_runtime_str!("parity-rococo-v1.6"),
impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS,
#[cfg(feature = "disable-runtime-api")]
apis: sp_version::create_apis_vec![[]],
transaction_version: 0,
};
/// The BABE epoch configuration at genesis.
pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration =
babe_primitives::BabeEpochConfiguration {
c: PRIMARY_PROBABILITY,
allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots,
};
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// `BlockId` type as expected by this runtime.
/// The `SignedExtension` to the basic transaction logic.
frame_system::CheckSpecVersion<Runtime>,
frame_system::CheckTxVersion<Runtime>,
frame_system::CheckGenesis<Runtime>,
frame_system::CheckMortality<Runtime>,
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
/// Migrate from `PalletVersion` to the new `StorageVersion`
pub struct MigratePalletVersionToStorageVersion;
impl OnRuntimeUpgrade for MigratePalletVersionToStorageVersion {
fn on_runtime_upgrade() -> frame_support::weights::Weight {
frame_support::migrations::migrate_from_pallet_version_to_storage_version::<
AllPalletsWithSystem,
>(&RocksDbWeight::get())
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
Runtime,
Block,
frame_system::ChainContext<Runtime>,
Runtime,
AllPallets,
MigratePalletVersionToStorageVersion,
/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<Call, SignedExtra>;
impl_opaque_keys! {
pub struct SessionKeys {
pub grandpa: Grandpa,
pub babe: Babe,
pub im_online: ImOnline,
pub para_validator: Initializer,
pub para_assignment: ParaSessionInfo,
pub authority_discovery: AuthorityDiscovery,
pub beefy: Beefy,
}
}
construct_runtime! {
pub enum Runtime where
Block = Block,
NodeBlock = primitives::v1::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
Shaun Wang
committed
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Shaun Wang
committed
Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned},
Shaun Wang
committed
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
Indices: pallet_indices::{Pallet, Call, Storage, Config<T>, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
Shaun Wang
committed
Authorship: pallet_authorship::{Pallet, Call, Storage},
Offences: pallet_offences::{Pallet, Storage, Event},
Shaun Wang
committed
Historical: session_historical::{Pallet},
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned},
ImOnline: pallet_im_online::{Pallet, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config},
Shaun Wang
committed
ParachainsOrigin: parachains_origin::{Pallet, Origin},
Configuration: parachains_configuration::{Pallet, Call, Storage, Config<T>},
ParasShared: parachains_shared::{Pallet, Call, Storage},
ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event<T>},
ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent},
ParaScheduler: parachains_scheduler::{Pallet, Storage},
Paras: parachains_paras::{Pallet, Call, Storage, Event, Config},
Shaun Wang
committed
Initializer: parachains_initializer::{Pallet, Call, Storage},
Dmp: parachains_dmp::{Pallet, Call, Storage},
Ump: parachains_ump::{Pallet, Call, Storage, Event},
Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event<T>, Config},
ParaSessionInfo: parachains_session_info::{Pallet, Storage},
Shaun Wang
committed
// Parachain Onboarding Pallets
Shaun Wang
committed
Registrar: paras_registrar::{Pallet, Call, Storage, Event<T>},
Auctions: auctions::{Pallet, Call, Storage, Event<T>},
Crowdloan: crowdloan::{Pallet, Call, Storage, Event<T>},
Slots: slots::{Pallet, Call, Storage, Event<T>},
Shaun Wang
committed
ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call},
Shaun Wang
committed
Sudo: pallet_sudo::{Pallet, Call, Storage, Event<T>, Config<T>},
Mmr: pallet_mmr::{Pallet, Storage},
Beefy: pallet_beefy::{Pallet, Config<T>, Storage},
MmrLeaf: pallet_beefy_mmr::{Pallet, Storage},
// It might seem strange that we add both sides of the bridge to the same runtime. We do this because this
// runtime as shared by both the Rococo and Wococo chains. When running as Rococo we only use
// `BridgeWococoGrandpa`, and vice versa.
BridgeRococoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Config<T>} = 40,
BridgeWococoGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Storage, Config<T>} = 41,
// Validator Manager pallet.
ValidatorManager: validator_manager::{Pallet, Call, Storage, Event<T>},
// Bridge messages support. The same story as with the bridge grandpa pallet above ^^^ - when we're
// running as Rococo we only use `BridgeWococoMessages`/`BridgeWococoMessagesDispatch`, and vice versa.
BridgeRococoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>} = 43,
BridgeWococoMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 44,
BridgeRococoMessagesDispatch: pallet_bridge_dispatch::{Pallet, Event<T>} = 45,
BridgeWococoMessagesDispatch: pallet_bridge_dispatch::<Instance1>::{Pallet, Event<T>} = 46,
// A "council"
Collective: pallet_collective::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 80,
Membership: pallet_membership::{Pallet, Call, Storage, Event<T>, Config<T>} = 81,
Utility: pallet_utility::{Pallet, Call, Event} = 90,
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 91,
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin} = 99,
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
fn filter(_call: &Call) -> bool {
true
}
}
parameter_types! {
pub const Version: RuntimeVersion = VERSION;
pub const SS58Prefix: u8 = 42;
impl frame_system::Config for Runtime {
type BlockWeights = BlockWeights;
type BlockLength = BlockLength;
type DbWeight = RocksDbWeight;
type Origin = Origin;
type Call = Call;
type Index = Nonce;
type BlockNumber = BlockNumber;
type Hash = Hash;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = AccountIdLookup<AccountId, ()>;
type Header = generic::Header<BlockNumber, BlakeTwo256>;
type Event = Event;
type BlockHashCount = BlockHashCount;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
}
parameter_types! {
pub const ValidationUpgradeFrequency: BlockNumber = 2 * DAYS;
pub const ValidationUpgradeDelay: BlockNumber = 8 * HOURS;
pub const SlashPeriod: BlockNumber = 7 * DAYS;
}
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
where
fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
call: Call,
public: <Signature as Verify>::Signer,
account: AccountId,
nonce: <Runtime as frame_system::Config>::Index,
) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
use sp_runtime::traits::StaticLookup;
let period =
BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
let current_block = System::block_number()
.saturated_into::<u64>()
// The `System::block_number` is initialized with `n+1`,
// so the actual block number is `n`.
.saturating_sub(1);
let tip = 0;
let extra: SignedExtra = (
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
period,
current_block,
)),
frame_system::CheckNonce::<Runtime>::from(nonce),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
let raw_payload = SignedPayload::new(call, extra)
.map_err(|e| {
log::warn!("Unable to create signed payload: {:?}", e);
})
.ok()?;
let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
let (call, extra, _) = raw_payload.deconstruct();
let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
Some((call, (address, signature, extra)))
impl frame_system::offchain::SigningTypes for Runtime {
type Public = <Signature as Verify>::Signer;
type Signature = Signature;
}
/// Special `FullIdentificationOf` implementation that is returning for every input `Some(Default::default())`.
pub struct FullIdentificationOf;
impl sp_runtime::traits::Convert<AccountId, Option<()>> for FullIdentificationOf {
fn convert(_: AccountId) -> Option<()> {
Some(Default::default())
}
impl pallet_session::historical::Config for Runtime {
type FullIdentification = ();
type FullIdentificationOf = FullIdentificationOf;
pub SessionDuration: BlockNumber = EpochDurationInBlocks::get() as _;
}
parameter_types! {
pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}
impl pallet_im_online::Config for Runtime {
type AuthorityId = ImOnlineId;
type Event = Event;
type NextSessionRotation = Babe;
type UnsignedPriority = ImOnlineUnsignedPriority;
type WeightInfo = ();
}
parameter_types! {
pub const ExistentialDeposit: Balance = 1 * CENTS;
pub const MaxLocks: u32 = 50;
impl pallet_balances::Config for Runtime {
type Balance = Balance;
type DustRemoval = ();
type Event = Event;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type MaxLocks = MaxLocks;
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
where
Call: From<C>,
{
type OverarchingCall = Call;
type Extrinsic = UncheckedExtrinsic;
}
parameter_types! {
pub const MaxRetries: u32 = 3;
}
impl pallet_offences::Config for Runtime {
type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
impl pallet_authority_discovery::Config for Runtime {}
parameter_types! {
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
}
impl pallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = Babe;
type MinimumPeriod = MinimumPeriod;
type WeightInfo = ();
}
parameter_types! {
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
}
impl pallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, ToAuthor<Runtime>>;
type TransactionByteFee = TransactionByteFee;
type WeightToFee = WeightToFee;
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
}
parameter_types! {
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}
/// Special `ValidatorIdOf` implementation that is just returning the input as result.
pub struct ValidatorIdOf;
impl sp_runtime::traits::Convert<AccountId, Option<AccountId>> for ValidatorIdOf {
fn convert(a: AccountId) -> Option<AccountId> {
Some(a)
}
impl pallet_session::Config for Runtime {
type Event = Event;
type ValidatorId = AccountId;
type ValidatorIdOf = ValidatorIdOf;
type ShouldEndSession = Babe;
type NextSessionRotation = Babe;
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, ValidatorManager>;
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
type WeightInfo = ();
}
parameter_types! {
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
pub ReportLongevity: u64 = EpochDurationInBlocks::get() as u64 * 10;
impl pallet_babe::Config for Runtime {
type EpochDuration = EpochDurationInBlocks;
type ExpectedBlockTime = ExpectedBlockTime;
// session module is the trigger
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
)>>::IdentificationTuple;
type HandleEquivocation =
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
type WeightInfo = ();
}
parameter_types! {
pub const IndexDeposit: Balance = 1 * DOLLARS;
}
impl pallet_indices::Config for Runtime {
type AccountIndex = AccountIndex;
type Currency = Balances;
type Deposit = IndexDeposit;
type Event = Event;
type WeightInfo = ();
}
parameter_types! {
pub const AttestationPeriod: BlockNumber = 50;
}
impl pallet_grandpa::Config for Runtime {
type Event = Event;
type Call = Call;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof =
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
GrandpaId,
)>>::IdentificationTuple;
type HandleEquivocation = pallet_grandpa::EquivocationHandler<
Self::KeyOwnerIdentification,
Offences,
ReportLongevity,
>;
type WeightInfo = ();
}
parameter_types! {
pub const UncleGenerations: u32 = 0;
}
impl pallet_authorship::Config for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
type UncleGenerations = UncleGenerations;
type FilterUncle = ();
impl parachains_origin::Config for Runtime {}
impl parachains_configuration::Config for Runtime {}
impl parachains_shared::Config for Runtime {}
/// Special `RewardValidators` that does nothing ;)
pub struct RewardValidators;
impl runtime_parachains::inclusion::RewardValidators for RewardValidators {
fn reward_backing(_: impl IntoIterator<Item = ValidatorIndex>) {}
fn reward_bitfields(_: impl IntoIterator<Item = ValidatorIndex>) {}
impl parachains_inclusion::Config for Runtime {
type RewardValidators = RewardValidators;
impl parachains_paras::Config for Runtime {
parameter_types! {
pub const RocLocation: MultiLocation = MultiLocation::Null;
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
pub const Ancestry: MultiLocation = MultiLocation::Null;
pub CheckAccount: AccountId = XcmPallet::check_account();
pub type SovereignAccountOf =
(ChildParachainConvertsVia<ParaId, AccountId>, AccountId32Aliases<RococoNetwork, AccountId>);
pub type LocalAssetTransactor = XcmCurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching the given location or name:
IsConcrete<RocLocation>,
// We can convert the MultiLocations with our converter above:
SovereignAccountOf,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
AccountId,
// It's a native asset so we keep track of the teleports to maintain total issuance.
CheckAccount,
>;
SovereignSignedViaLocation<SovereignAccountOf, Origin>,
ChildParachainAsNative<parachains_origin::Origin, Origin>,
SignedAccountId32AsNative<RococoNetwork, Origin>,
ChildSystemParachainAsSuperuser<ParaId, Origin>,
);
parameter_types! {
pub const BaseXcmWeight: Weight = 100_000;
}
/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our
/// individual routers.
pub type XcmRouter = (
// Only one router so far - use DMP to communicate with child parachains.
xcm_sender::ChildParachainRouter<Runtime>,
);
use xcm::v0::{
Junction::Parachain,
MultiAsset,
MultiAsset::AllConcreteFungible,
MultiLocation::{Null, X1},
};
parameter_types! {
pub const RococoForTick: (MultiAsset, MultiLocation) =
(AllConcreteFungible { id: Null }, X1(Parachain(100)));
pub const RococoForTrick: (MultiAsset, MultiLocation) =
(AllConcreteFungible { id: Null }, X1(Parachain(110)));
pub const RococoForTrack: (MultiAsset, MultiLocation) =
(AllConcreteFungible { id: Null }, X1(Parachain(120)));
pub const RococoForStatemint: (MultiAsset, MultiLocation) =
(AllConcreteFungible { id: Null }, X1(Parachain(1001)));
}
pub type TrustedTeleporters = (
xcm_builder::Case<RococoForTick>,
xcm_builder::Case<RococoForTrick>,
xcm_builder::Case<RococoForTrack>,
);
parameter_types! {
pub AllowUnpaidFrom: Vec<MultiLocation> =
X1(Parachain(100)),
X1(Parachain(110)),
X1(Parachain(120)),
}
use xcm_builder::{AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, TakeWeightCredit};
pub type Barrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<All<MultiLocation>>,
AllowUnpaidExecutionFrom<IsInVec<AllowUnpaidFrom>>, // <- Trusted parachains get free execution
);
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type Call = Call;
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = LocalOriginConverter;
type IsReserve = ();
type IsTeleporter = TrustedTeleporters;
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Trader = UsingComponents<WeightToFee, RocLocation, AccountId, Balances, ToAuthor<Runtime>>;
parameter_types! {
pub const CollectiveBodyId: BodyId = BodyId::Unit;
}
/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
/// of this chain.
pub type LocalOriginToLocation = (
// We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the
// `Unit` body.
BackingToPlurality<Origin, pallet_collective::Origin<Runtime>, CollectiveBodyId>,
// And a usual Signed origin to be used in XCM as a corresponding AccountId32
SignedToAccountId32<Origin, AccountId, RococoNetwork>,
pub struct OnlyWithdrawTeleportForAccounts;
impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)>
for OnlyWithdrawTeleportForAccounts
{
fn contains((ref origin, ref msg): &(MultiLocation, Xcm<Call>)) -> bool {
use xcm::v0::{
Junction::{AccountId32, Plurality},
MultiAsset::{All, ConcreteFungible},
Order::{BuyExecution, DepositAsset, InitiateTeleport},
Xcm::WithdrawAsset,
};
match origin {
// Root and collective are allowed to execute anything.
Null | X1(Plurality { .. }) => true,
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
X1(AccountId32 { .. }) => {
// An account ID trying to send a message. We ensure that it's sensible.
// This checks that it's of the form:
// WithdrawAsset {
// assets: [ ConcreteFungible { id: Null } ],
// effects: [ BuyExecution, InitiateTeleport {
// assets: All,
// dest: Parachain,
// effects: [ BuyExecution, DepositAssets {
// assets: All,
// dest: AccountId32,
// } ]
// } ]
// }
matches!(msg, WithdrawAsset { ref assets, ref effects }
if assets.len() == 1
&& matches!(assets[0], ConcreteFungible { id: Null, .. })
&& effects.len() == 2
&& matches!(effects[0], BuyExecution { .. })
&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
if assets.len() == 1
&& matches!(assets[0], All)
&& effects.len() == 2
&& matches!(effects[0], BuyExecution { .. })
&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
if assets.len() == 1
&& matches!(assets[0], All)
)
)
)
// Nobody else is allowed to execute anything.
_ => false,
}
}
}
impl pallet_xcm::Config for Runtime {
type Event = Event;
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
type XcmRouter = XcmRouter;
// Anyone can execute XCM messages locally...
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
// ...but they must match our filter, which requires them to be a simple withdraw + teleport.
type XcmExecuteFilter = OnlyWithdrawTeleportForAccounts;
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
impl parachains_session_info::Config for Runtime {}
parameter_types! {
pub const FirstMessageFactorPercent: u64 = 100;
}
impl parachains_ump::Config for Runtime {
type Event = Event;
type UmpSink = crate::parachains_ump::XcmSink<XcmExecutor<XcmConfig>, Runtime>;
type FirstMessageFactorPercent = FirstMessageFactorPercent;
impl parachains_dmp::Config for Runtime {}
impl parachains_hrmp::Config for Runtime {
type Origin = Origin;
impl parachains_paras_inherent::Config for Runtime {}
impl parachains_scheduler::Config for Runtime {}
impl parachains_initializer::Config for Runtime {
type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
type ForceOrigin = EnsureRoot<AccountId>;
impl paras_sudo_wrapper::Config for Runtime {}
parameter_types! {
pub const ParaDeposit: Balance = 5 * DOLLARS;
pub const DataDepositPerByte: Balance = deposit(0, 1);
}
impl paras_registrar::Config for Runtime {
type OnSwap = (Crowdloan, Slots);
type ParaDeposit = ParaDeposit;
type DataDepositPerByte = DataDepositPerByte;
type WeightInfo = paras_registrar::TestWeightInfo;
/// An insecure randomness beacon that uses the parent block hash as random material.
///
/// THIS SHOULD ONLY BE USED FOR TESTING PURPOSES.
pub struct ParentHashRandomness;
impl pallet_beefy::Config for Runtime {
}
impl pallet_mmr::Config for Runtime {
const INDEXING_PREFIX: &'static [u8] = b"mmr";
type Hashing = Keccak256;
type Hash = <Keccak256 as traits::Hash>::Output;
type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest<Runtime>;
type WeightInfo = ();
type LeafData = pallet_beefy_mmr::Pallet<Runtime>;
}
pub struct ParasProvider;
impl pallet_beefy_mmr::ParachainHeadsProvider for ParasProvider {
fn parachain_heads() -> Vec<(u32, Vec<u8>)> {
Paras::parachains()
.into_iter()
.filter_map(|id| Paras::para_head(&id).map(|head| (id.into(), head.0)))
parameter_types! {
/// Version of the produced MMR leaf.
///
/// The version consists of two parts;
/// - `major` (3 bits)
/// - `minor` (5 bits)
///
/// `major` should be updated only if decoding the previous MMR Leaf format from the payload
/// is not possible (i.e. backward incompatible change).
/// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE
/// encoding does not prevent old leafs from being decoded.
///
/// Hence we expect `major` to be changed really rarely (think never).
/// See [`MmrLeafVersion`] type documentation for more details.
pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0);
}
impl pallet_beefy_mmr::Config for Runtime {
type LeafVersion = LeafVersion;
type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum;
type ParachainHeads = ParasProvider;
/// This is a pretty unscientific cap.
///
/// Note that once this is hit the pallet will essentially throttle incoming requests down to one
/// call per block.
pub const MaxRequests: u32 = 4 * HOURS as u32;
/// Number of headers to keep.
///
/// Assuming the worst case of every header being finalized, we will keep headers at least for a
/// week.
pub const HeadersToKeep: u32 = 7 * DAYS as u32;
}
pub type RococoGrandpaInstance = ();
impl pallet_bridge_grandpa::Config for Runtime {
type BridgedChain = bp_rococo::Rococo;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type WeightInfo = pallet_bridge_grandpa::weights::RialtoWeight<Runtime>;
}
pub type WococoGrandpaInstance = pallet_bridge_grandpa::Instance1;
impl pallet_bridge_grandpa::Config<WococoGrandpaInstance> for Runtime {
type BridgedChain = bp_wococo::Wococo;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type WeightInfo = pallet_bridge_grandpa::weights::RialtoWeight<Runtime>;
}
// Instance that is "deployed" at Wococo chain. Responsible for dispatching Rococo -> Wococo messages.
pub type AtWococoFromRococoMessagesDispatch = pallet_bridge_dispatch::DefaultInstance;
impl pallet_bridge_dispatch::Config<AtWococoFromRococoMessagesDispatch> for Runtime {
type Event = Event;
type MessageId = (bp_messages::LaneId, bp_messages::MessageNonce);
type Call = Call;
type CallFilter = frame_support::traits::AllowAll;
type EncodedCall = bridge_messages::FromRococoEncodedCall;
type SourceChainAccountId = bp_wococo::AccountId;
type TargetChainAccountPublic = sp_runtime::MultiSigner;
type TargetChainSignature = sp_runtime::MultiSignature;
type AccountIdConverter = bp_rococo::AccountIdConverter;
}
// Instance that is "deployed" at Rococo chain. Responsible for dispatching Wococo -> Rococo messages.
pub type AtRococoFromWococoMessagesDispatch = pallet_bridge_dispatch::Instance1;
impl pallet_bridge_dispatch::Config<AtRococoFromWococoMessagesDispatch> for Runtime {
type Event = Event;
type MessageId = (bp_messages::LaneId, bp_messages::MessageNonce);
type Call = Call;
type CallFilter = frame_support::traits::AllowAll;
type EncodedCall = bridge_messages::FromWococoEncodedCall;
type SourceChainAccountId = bp_rococo::AccountId;
type TargetChainAccountPublic = sp_runtime::MultiSigner;
type TargetChainSignature = sp_runtime::MultiSignature;
type AccountIdConverter = bp_wococo::AccountIdConverter;
}
parameter_types! {
pub const MaxMessagesToPruneAtOnce: bp_messages::MessageNonce = 8;
pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce =
bp_rococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE;
pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce =
bp_rococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE;
pub const RootAccountForPayments: Option<AccountId> = None;
}
// Instance that is "deployed" at Wococo chain. Responsible for sending Wococo -> Rococo messages
// and receiving Rococo -> Wococo messages.
pub type AtWococoWithRococoMessagesInstance = pallet_bridge_messages::DefaultInstance;
impl pallet_bridge_messages::Config<AtWococoWithRococoMessagesInstance> for Runtime {
type Event = Event;
type WeightInfo = pallet_bridge_messages::weights::RialtoWeight<Runtime>;
type Parameter = ();
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
type OutboundPayload = crate::bridge_messages::ToRococoMessagePayload;
type OutboundMessageFee = bp_wococo::Balance;
type InboundPayload = crate::bridge_messages::FromRococoMessagePayload;
type InboundMessageFee = bp_rococo::Balance;
type InboundRelayer = bp_rococo::AccountId;
type AccountIdConverter = bp_wococo::AccountIdConverter;
type TargetHeaderChain = crate::bridge_messages::RococoAtWococo;
type LaneMessageVerifier = crate::bridge_messages::ToRococoMessageVerifier;
type MessageDeliveryAndDispatchPayment =
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
Runtime,
pallet_balances::Pallet<Runtime>,
crate::bridge_messages::GetDeliveryConfirmationTransactionFee,
RootAccountForPayments,
>;
type OnDeliveryConfirmed = ();
type SourceHeaderChain = crate::bridge_messages::RococoAtWococo;
type MessageDispatch = crate::bridge_messages::FromRococoMessageDispatch;
}
// Instance that is "deployed" at Rococo chain. Responsible for sending Rococo -> Wococo messages
// and receiving Wococo -> Rococo messages.
pub type AtRococoWithWococoMessagesInstance = pallet_bridge_messages::Instance1;
impl pallet_bridge_messages::Config<AtRococoWithWococoMessagesInstance> for Runtime {
type Event = Event;
type WeightInfo = pallet_bridge_messages::weights::RialtoWeight<Runtime>;
type Parameter = ();
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
type OutboundPayload = crate::bridge_messages::ToWococoMessagePayload;
type OutboundMessageFee = bp_rococo::Balance;
type InboundPayload = crate::bridge_messages::FromWococoMessagePayload;
type InboundMessageFee = bp_wococo::Balance;
type InboundRelayer = bp_wococo::AccountId;
type AccountIdConverter = bp_rococo::AccountIdConverter;
type TargetHeaderChain = crate::bridge_messages::WococoAtRococo;
type LaneMessageVerifier = crate::bridge_messages::ToWococoMessageVerifier;
type MessageDeliveryAndDispatchPayment =
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
Runtime,
pallet_balances::Pallet<Runtime>,
crate::bridge_messages::GetDeliveryConfirmationTransactionFee,
RootAccountForPayments,
>;
type OnDeliveryConfirmed = ();
type SourceHeaderChain = crate::bridge_messages::WococoAtRococo;
type MessageDispatch = crate::bridge_messages::FromWococoMessageDispatch;
}
impl Randomness<Hash, BlockNumber> for ParentHashRandomness {
fn random(subject: &[u8]) -> (Hash, BlockNumber) {
(System::parent_hash(), subject)
.using_encoded(sp_io::hashing::blake2_256)
.into(),
System::block_number(),