#![cfg_attr(not(feature = "std"), no_std)]
#![recursion_limit = "256"]
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
#[cfg(feature = "std")]
#[allow(clippy::expect_used)]
pub fn wasm_binary_unwrap() -> &'static [u8] {
WASM_BINARY.expect(
"wasm binary is not available. This means the client is \
built with `WASM_BINARY` flag and it is only usable for \
production chains. Please rebuild with the flag disabled.",
)
}
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
use cumulus_pallet_parachain_system::{RelayNumberMonotonicallyIncreases, RelaychainDataProvider};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, ConvertInto, IdentityLookup},
DispatchError,
};
use pallet_collective::Members;
#[cfg(any(feature = "runtime-benchmarks", feature = "test"))]
use pallet_collective::ProposalCount;
use parity_scale_codec::{Decode, Encode};
use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use common_primitives::node::{
AccountId, Address, Balance, BlockNumber, Hash, Header, Index, ProposalProvider, Signature,
UtilityProvider,
};
pub use common_runtime::{
constants::{currency::EXISTENTIAL_DEPOSIT, *},
fee::WeightToFee,
prod_or_testnet_or_local,
proxy::ProxyType,
};
use frame_support::{
construct_runtime,
dispatch::{DispatchClass, GetDispatchInfo, Pays},
ensure,
pallet_prelude::{DispatchResultWithPostInfo, TypeInfo},
parameter_types,
traits::{
fungible::HoldConsideration,
tokens::{PayFromAccount, UnityAssetBalanceConversion},
ConstBool, ConstU128, ConstU32, ConstU64, EitherOfDiverse, EqualPrivilegeOnly,
InstanceFilter, LinearStoragePrice,
},
weights::{ConstantMultiplier, Weight},
Twox128,
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot, EnsureSigned,
};
use sp_std::boxed::Box;
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_runtime::{MultiAddress, Perbill, Permill};
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
pub use pallet_capacity;
pub use pallet_frequency_tx_payment::{capacity_stable_weights, types::GetStableWeight};
pub use pallet_msa;
pub use pallet_passkey;
pub use pallet_schemas;
pub use pallet_time_release;
use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
pub use common_runtime::{
constants::MaxSchemaGrants,
weights,
weights::{block_weights::BlockExecutionWeight, extrinsic_weights::ExtrinsicBaseWeight},
};
use frame_support::traits::Contains;
use common_primitives::{
msa::MessageSourceId,
schema::SchemaId,
stateful_storage::{PageHash, PageId},
};
use common_runtime::weights::rocksdb_weights::constants::RocksDbWeight;
#[cfg(feature = "try-runtime")]
use frame_support::traits::{TryStateSelect, UpgradeCheckSelect};
use sp_runtime::{
traits::{DispatchInfoOf, SignedExtension},
transaction_validity::{
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
},
};
pub struct CouncilProposalProvider;
impl ProposalProvider<AccountId, RuntimeCall> for CouncilProposalProvider {
fn propose(
who: AccountId,
threshold: u32,
proposal: Box<RuntimeCall>,
) -> Result<(u32, u32), DispatchError> {
let length_bound: u32 = proposal.using_encoded(|p| p.len() as u32);
Council::do_propose_proposed(who, threshold, proposal, length_bound)
}
fn propose_with_simple_majority(
who: AccountId,
proposal: Box<RuntimeCall>,
) -> Result<(u32, u32), DispatchError> {
let members = Members::<Runtime, CouncilCollective>::get();
let threshold: u32 = ((members.len() / 2) + 1) as u32;
let length_bound: u32 = proposal.using_encoded(|p| p.len() as u32);
Council::do_propose_proposed(who, threshold, proposal, length_bound)
}
#[cfg(any(feature = "runtime-benchmarks", feature = "test"))]
fn proposal_count() -> u32 {
ProposalCount::<Runtime, CouncilCollective>::get()
}
}
pub struct CapacityBatchProvider;
impl UtilityProvider<RuntimeOrigin, RuntimeCall> for CapacityBatchProvider {
fn batch_all(origin: RuntimeOrigin, calls: Vec<RuntimeCall>) -> DispatchResultWithPostInfo {
Utility::batch_all(origin, calls)
}
}
pub struct BaseCallFilter;
impl Contains<RuntimeCall> for BaseCallFilter {
fn contains(call: &RuntimeCall) -> bool {
#[cfg(not(feature = "frequency"))]
{
match call {
RuntimeCall::Utility(pallet_utility_call) =>
Self::is_utility_call_allowed(pallet_utility_call),
_ => true,
}
}
#[cfg(feature = "frequency")]
{
match call {
RuntimeCall::Utility(pallet_utility_call) =>
Self::is_utility_call_allowed(pallet_utility_call),
RuntimeCall::Msa(pallet_msa::Call::create_provider { .. }) => false,
RuntimeCall::Schemas(pallet_schemas::Call::create_schema { .. }) => false,
RuntimeCall::Schemas(pallet_schemas::Call::create_schema_v2 { .. }) => false,
RuntimeCall::Schemas(pallet_schemas::Call::create_schema_v3 { .. }) => false,
_ => true,
}
}
}
}
impl BaseCallFilter {
fn is_utility_call_allowed(call: &pallet_utility::Call<Runtime>) -> bool {
match call {
pallet_utility::Call::batch { calls, .. } |
pallet_utility::Call::batch_all { calls, .. } |
pallet_utility::Call::force_batch { calls, .. } => calls.iter().any(Self::is_batch_call_allowed),
_ => true,
}
}
fn is_batch_call_allowed(call: &RuntimeCall) -> bool {
match call {
RuntimeCall::Utility(pallet_utility::Call::batch { .. }) |
RuntimeCall::Utility(pallet_utility::Call::batch_all { .. }) |
RuntimeCall::Utility(pallet_utility::Call::force_batch { .. }) => false,
RuntimeCall::FrequencyTxPayment(..) => false,
RuntimeCall::Msa(pallet_msa::Call::create_provider { .. }) |
RuntimeCall::Schemas(pallet_schemas::Call::create_schema { .. }) |
RuntimeCall::Schemas(pallet_schemas::Call::create_schema_v2 { .. }) => false,
RuntimeCall::Schemas(pallet_schemas::Call::create_schema_v3 { .. }) => false,
_ if Self::is_pays_no_call(call) => false,
_ => true,
}
}
fn is_pays_no_call(call: &RuntimeCall) -> bool {
call.get_dispatch_info().pays_fee == Pays::No
}
}
impl InstanceFilter<RuntimeCall> for ProxyType {
fn filter(&self, c: &RuntimeCall) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer => matches!(
c,
RuntimeCall::Capacity(..)
| RuntimeCall::CollatorSelection(..)
| RuntimeCall::Council(..)
| RuntimeCall::Democracy(..)
| RuntimeCall::FrequencyTxPayment(..) | RuntimeCall::Handles(..)
| RuntimeCall::Messages(..)
| RuntimeCall::Msa(..)
| RuntimeCall::Multisig(..)
| RuntimeCall::Preimage(..)
| RuntimeCall::Scheduler(..)
| RuntimeCall::Schemas(..)
| RuntimeCall::Session(..)
| RuntimeCall::StatefulStorage(..)
| RuntimeCall::TechnicalCommittee(..)
| RuntimeCall::TimeRelease(pallet_time_release::Call::claim{..})
| RuntimeCall::TimeRelease(pallet_time_release::Call::claim_for{..})
| RuntimeCall::Treasury(..)
| RuntimeCall::Utility(..) ),
ProxyType::Governance => matches!(
c,
RuntimeCall::Treasury(..) |
RuntimeCall::Democracy(..) |
RuntimeCall::TechnicalCommittee(..) |
RuntimeCall::Council(..) |
RuntimeCall::Utility(..) ),
ProxyType::Staking => {
matches!(
c,
RuntimeCall::Capacity(pallet_capacity::Call::stake { .. }) |
RuntimeCall::CollatorSelection(
pallet_collator_selection::Call::set_candidacy_bond { .. }
)
)
},
ProxyType::CancelProxy => {
matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }))
},
}
}
fn is_superset(&self, o: &Self) -> bool {
match (self, o) {
(x, y) if x == y => true,
(ProxyType::Any, _) => true,
(_, ProxyType::Any) => false,
(ProxyType::NonTransfer, _) => true,
_ => false,
}
}
}
pub struct PasskeyCallFilter;
impl Contains<RuntimeCall> for PasskeyCallFilter {
fn contains(call: &RuntimeCall) -> bool {
match call {
#[cfg(feature = "runtime-benchmarks")]
RuntimeCall::System(frame_system::Call::remark { .. }) => true,
RuntimeCall::Balances(_) | RuntimeCall::Capacity(_) => true,
_ => false,
}
}
}
pub type SignedExtra = (
frame_system::CheckNonZeroSender<Runtime>,
(frame_system::CheckSpecVersion<Runtime>, frame_system::CheckTxVersion<Runtime>),
frame_system::CheckGenesis<Runtime>,
frame_system::CheckEra<Runtime>,
common_runtime::extensions::check_nonce::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_frequency_tx_payment::ChargeFrqTransactionPayment<Runtime>,
pallet_msa::CheckFreeExtrinsicUse<Runtime>,
pallet_handles::handles_signed_extension::HandlesSignedExtension<Runtime>,
StaleHashCheckExtension,
frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
);
pub type SignedBlock = generic::SignedBlock<Block>;
pub type BlockId = generic::BlockId<Block>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
pub type Executive = frame_executive::Executive<
Runtime,
Block,
frame_system::ChainContext<Runtime>,
Runtime,
AllPalletsWithSystem,
(pallet_schemas::migration::v4::MigrateToV4<Runtime>,),
>;
pub mod apis;
pub mod opaque {
use super::*;
use sp_runtime::{
generic,
traits::{BlakeTwo256, Hash as HashT},
};
pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
pub type BlockId = generic::BlockId<Block>;
pub type Hash = <BlakeTwo256 as HashT>::Output;
}
impl_opaque_keys! {
pub struct SessionKeys {
pub aura: Aura,
}
}
#[cfg(feature = "frequency")]
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("frequency"),
impl_name: create_runtime_str!("frequency"),
authoring_version: 1,
spec_version: 111,
impl_version: 0,
apis: apis::RUNTIME_API_VERSIONS,
transaction_version: 1,
state_version: 1,
};
#[cfg(not(feature = "frequency"))]
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("frequency-testnet"),
impl_name: create_runtime_str!("frequency"),
authoring_version: 1,
spec_version: 111,
impl_version: 0,
apis: apis::RUNTIME_API_VERSIONS,
transaction_version: 1,
state_version: 1,
};
#[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);
weights.reserved = Some(
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
);
})
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic();
}
impl frame_system::Config for Runtime {
type RuntimeTask = RuntimeTask;
type AccountId = AccountId;
type BaseCallFilter = BaseCallFilter;
type RuntimeCall = RuntimeCall;
type Lookup = AccountIdLookup<AccountId, ()>;
type Nonce = Index;
type Block = Block;
type Hash = Hash;
type Hashing = BlakeTwo256;
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
type BlockHashCount = BlockHashCount;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type DbWeight = RocksDbWeight;
type SystemWeightInfo = ();
type BlockWeights = RuntimeBlockWeights;
type BlockLength = RuntimeBlockLength;
type SS58Prefix = Ss58Prefix;
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
#[cfg(feature = "frequency-no-relay")]
type OnSetCode = ();
type MaxConsumers = FrameSystemMaxConsumers;
type SingleBlockMigrations = ();
type MultiBlockMigrator = ();
type PreInherents = ();
type PostInherents = ();
type PostTransactions = ();
}
impl pallet_msa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_msa::weights::SubstrateWeight<Runtime>;
type ConvertIntoAccountId32 = ConvertInto;
type MaxPublicKeysPerMsa = MsaMaxPublicKeysPerMsa;
type MaxSchemaGrantsPerDelegation = MaxSchemaGrants;
type MaxProviderNameSize = MsaMaxProviderNameSize;
type SchemaValidator = Schemas;
type HandleProvider = Handles;
type MortalityWindowSize = MSAMortalityWindowSize;
type MaxSignaturesStored = MSAMaxSignaturesStored;
type Proposal = RuntimeCall;
type ProposalProvider = CouncilProposalProvider;
type CreateProviderViaGovernanceOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureMembers<AccountId, CouncilCollective, 1>,
>;
}
impl pallet_capacity::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_capacity::weights::SubstrateWeight<Runtime>;
type Currency = Balances;
type MinimumStakingAmount = CapacityMinimumStakingAmount;
type MinimumTokenBalance = CapacityMinimumTokenBalance;
type TargetValidator = Msa;
type MaxUnlockingChunks = CapacityMaxUnlockingChunks;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = Msa;
type UnstakingThawPeriod = CapacityUnstakingThawPeriod;
type MaxEpochLength = CapacityMaxEpochLength;
type EpochNumber = u32;
type CapacityPerToken = CapacityPerToken;
type RuntimeFreezeReason = RuntimeFreezeReason;
}
impl pallet_schemas::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_schemas::weights::SubstrateWeight<Runtime>;
type MinSchemaModelSizeBytes = SchemasMinModelSizeBytes;
type MaxSchemaRegistrations = SchemasMaxRegistrations;
type SchemaModelMaxBytesBoundedVecLimit = SchemasMaxBytesBoundedVecLimit;
type Proposal = RuntimeCall;
type ProposalProvider = CouncilProposalProvider;
type CreateSchemaViaGovernanceOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<AccountId, CouncilCollective, 1, 2>,
>;
type MaxSchemaSettingsPerSchema = MaxSchemaSettingsPerSchema;
}
pub type DepositBase = ConstU128<{ currency::deposit(1, 88) }>;
pub type DepositFactor = ConstU128<{ currency::deposit(0, 32) }>;
pub type MaxSignatories = ConstU32<100>;
impl pallet_multisig::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type DepositBase = DepositBase;
type DepositFactor = DepositFactor;
type MaxSignatories = MaxSignatories;
type WeightInfo = weights::pallet_multisig::SubstrateWeight<Runtime>;
}
pub type MaxReleaseSchedules = ConstU32<{ MAX_RELEASE_SCHEDULES }>;
impl pallet_time_release::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type Currency = Balances;
type MinReleaseTransfer = MinReleaseTransfer;
type TransferOrigin = EnsureSigned<AccountId>;
type WeightInfo = pallet_time_release::weights::SubstrateWeight<Runtime>;
type MaxReleaseSchedules = MaxReleaseSchedules;
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
type BlockNumberProvider = RelaychainDataProvider<Runtime>;
#[cfg(feature = "frequency-no-relay")]
type BlockNumberProvider = System;
type RuntimeFreezeReason = RuntimeFreezeReason;
}
impl pallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = MinimumPeriod;
type WeightInfo = weights::pallet_timestamp::SubstrateWeight<Runtime>;
}
impl pallet_authorship::Config for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
type EventHandler = (CollatorSelection,);
}
impl pallet_balances::Config for Runtime {
type MaxLocks = BalancesMaxLocks;
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ConstU128<EXISTENTIAL_DEPOSIT>;
type AccountStore = System;
type WeightInfo = weights::pallet_balances::SubstrateWeight<Runtime>;
type MaxReserves = BalancesMaxReserves;
type ReserveIdentifier = [u8; 8];
type MaxFreezes = BalancesMaxFreezes;
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type FreezeIdentifier = RuntimeFreezeReason;
}
parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(10) * RuntimeBlockWeights::get().max_block;
pub MaxCollectivesProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block;
}
impl pallet_scheduler::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
type PalletsOrigin = OriginCaller;
type RuntimeCall = RuntimeCall;
type MaximumWeight = MaximumSchedulerWeight;
type ScheduleOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
>;
type MaxScheduledPerBlock = SchedulerMaxScheduledPerBlock;
type WeightInfo = weights::pallet_scheduler::SubstrateWeight<Runtime>;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type Preimages = Preimage;
}
parameter_types! {
pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
}
impl pallet_preimage::Config for Runtime {
type WeightInfo = weights::pallet_preimage::SubstrateWeight<Runtime>;
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type ManagerOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureMember<AccountId, TechnicalCommitteeCollective>,
>;
type Consideration = HoldConsideration<
AccountId,
Balances,
PreimageHoldReason,
LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
>;
}
type CouncilCollective = pallet_collective::Instance1;
impl pallet_collective::Config<CouncilCollective> for Runtime {
type RuntimeOrigin = RuntimeOrigin;
type Proposal = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type MotionDuration = CouncilMotionDuration;
type MaxProposals = CouncilMaxProposals;
type MaxMembers = CouncilMaxMembers;
type DefaultVote = pallet_collective::PrimeDefaultVote;
type WeightInfo = weights::pallet_collective_council::SubstrateWeight<Runtime>;
type SetMembersOrigin = EnsureRoot<Self::AccountId>;
type MaxProposalWeight = MaxCollectivesProposalWeight;
}
type TechnicalCommitteeCollective = pallet_collective::Instance2;
impl pallet_collective::Config<TechnicalCommitteeCollective> for Runtime {
type RuntimeOrigin = RuntimeOrigin;
type Proposal = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type MotionDuration = TCMotionDuration;
type MaxProposals = TCMaxProposals;
type MaxMembers = TCMaxMembers;
type DefaultVote = pallet_collective::PrimeDefaultVote;
type WeightInfo = weights::pallet_collective_technical_committee::SubstrateWeight<Runtime>;
type SetMembersOrigin = EnsureRoot<Self::AccountId>;
type MaxProposalWeight = MaxCollectivesProposalWeight;
}
impl pallet_democracy::Config for Runtime {
type CooloffPeriod = CooloffPeriod;
type Currency = Balances;
type EnactmentPeriod = EnactmentPeriod;
type RuntimeEvent = RuntimeEvent;
type FastTrackVotingPeriod = FastTrackVotingPeriod;
type InstantAllowed = frame_support::traits::ConstBool<true>;
type LaunchPeriod = LaunchPeriod;
type MaxProposals = DemocracyMaxProposals;
type MaxVotes = DemocracyMaxVotes;
type MinimumDeposit = MinimumDeposit;
type Scheduler = Scheduler;
type Slash = ();
type WeightInfo = weights::pallet_democracy::SubstrateWeight<Runtime>;
type VoteLockingPeriod = EnactmentPeriod;
type VotingPeriod = VotingPeriod;
type Preimages = Preimage;
type MaxDeposits = ConstU32<100>;
type MaxBlacklisted = ConstU32<100>;
type ExternalDefaultOrigin = EitherOfDiverse<
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>,
frame_system::EnsureRoot<AccountId>,
>;
type ExternalMajorityOrigin = EitherOfDiverse<
pallet_collective::EnsureProportionMoreThan<AccountId, CouncilCollective, 1, 2>,
frame_system::EnsureRoot<AccountId>,
>;
type ExternalOrigin = EitherOfDiverse<
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
frame_system::EnsureRoot<AccountId>,
>;
type SubmitOrigin = frame_system::EnsureSigned<AccountId>;
type FastTrackOrigin = EitherOfDiverse<
pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCommitteeCollective, 2, 3>,
frame_system::EnsureRoot<AccountId>,
>;
type InstantOrigin = EitherOfDiverse<
pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCommitteeCollective, 1, 1>,
frame_system::EnsureRoot<AccountId>,
>;
type PalletsOrigin = OriginCaller;
type CancellationOrigin = EitherOfDiverse<
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>,
EnsureRoot<AccountId>,
>;
type CancelProposalOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCommitteeCollective, 1, 1>,
>;
type BlacklistOrigin = EnsureRoot<AccountId>;
type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCommitteeCollective>;
}
parameter_types! {
pub TreasuryAccount: AccountId = TreasuryPalletId::get().into_account_truncating();
pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS;
}
impl pallet_treasury::Config for Runtime {
type PalletId = TreasuryPalletId;
type Currency = Balances;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = weights::pallet_treasury::SubstrateWeight<Runtime>;
type ApproveOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 5>,
>;
type RejectOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<AccountId, CouncilCollective, 1, 2>,
>;
type SpendOrigin = frame_support::traits::NeverEnsureOrigin<Balance>;
type OnSlash = ();
type ProposalBond = ProposalBondPercent;
type ProposalBondMinimum = ProposalBondMinimum;
type ProposalBondMaximum = ProposalBondMaximum;
type SpendPeriod = SpendPeriod;
type Burn = ();
type BurnDestination = ();
type SpendFunds = ();
type MaxApprovals = MaxApprovals;
type AssetKind = ();
type Beneficiary = AccountId;
type BeneficiaryLookup = IdentityLookup<Self::Beneficiary>;
type Paymaster = PayFromAccount<Balances, TreasuryAccount>;
type BalanceConverter = UnityAssetBalanceConversion;
type PayoutPeriod = PayoutSpendPeriod;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}
impl pallet_transaction_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
type WeightToFee = WeightToFee;
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
type OperationalFeeMultiplier = TransactionPaymentOperationalFeeMultiplier;
}
use pallet_frequency_tx_payment::Call as FrequencyPaymentCall;
use pallet_handles::Call as HandlesCall;
use pallet_messages::Call as MessagesCall;
use pallet_msa::Call as MsaCall;
use pallet_stateful_storage::Call as StatefulStorageCall;
use pallet_utility::Call as UtilityCall;
pub struct CapacityEligibleCalls;
impl GetStableWeight<RuntimeCall, Weight> for CapacityEligibleCalls {
fn get_stable_weight(call: &RuntimeCall) -> Option<Weight> {
use pallet_frequency_tx_payment::capacity_stable_weights::WeightInfo;
match call {
RuntimeCall::Msa(MsaCall::add_public_key_to_msa { .. }) => Some(
capacity_stable_weights::SubstrateWeight::<Runtime>::add_public_key_to_msa()
),
RuntimeCall::Msa(MsaCall::create_sponsored_account_with_delegation { add_provider_payload, .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::create_sponsored_account_with_delegation(add_provider_payload.schema_ids.len() as u32)),
RuntimeCall::Msa(MsaCall::grant_delegation { add_provider_payload, .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::grant_delegation(add_provider_payload.schema_ids.len() as u32)),
RuntimeCall::Messages(MessagesCall::add_ipfs_message { .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::add_ipfs_message()),
RuntimeCall::Messages(MessagesCall::add_onchain_message { payload, .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::add_onchain_message(payload.len() as u32)),
RuntimeCall::StatefulStorage(StatefulStorageCall::apply_item_actions { actions, ..}) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::apply_item_actions(StatefulStorage::sum_add_actions_bytes(actions))),
RuntimeCall::StatefulStorage(StatefulStorageCall::upsert_page { payload, ..}) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::upsert_page(payload.len() as u32)),
RuntimeCall::StatefulStorage(StatefulStorageCall::delete_page { .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::delete_page()),
RuntimeCall::StatefulStorage(StatefulStorageCall::apply_item_actions_with_signature { payload, ..}) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::apply_item_actions_with_signature(StatefulStorage::sum_add_actions_bytes(&payload.actions))),
RuntimeCall::StatefulStorage(StatefulStorageCall::apply_item_actions_with_signature_v2 { payload, ..}) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::apply_item_actions_with_signature(StatefulStorage::sum_add_actions_bytes(&payload.actions))),
RuntimeCall::StatefulStorage(StatefulStorageCall::upsert_page_with_signature { payload, ..}) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::upsert_page_with_signature(payload.payload.len() as u32 )),
RuntimeCall::StatefulStorage(StatefulStorageCall::upsert_page_with_signature_v2 { payload, ..}) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::upsert_page_with_signature(payload.payload.len() as u32 )),
RuntimeCall::StatefulStorage(StatefulStorageCall::delete_page_with_signature { .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::delete_page_with_signature()),
RuntimeCall::StatefulStorage(StatefulStorageCall::delete_page_with_signature_v2 { .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::delete_page_with_signature()),
RuntimeCall::Handles(HandlesCall::claim_handle { payload, .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::claim_handle(payload.base_handle.len() as u32)),
RuntimeCall::Handles(HandlesCall::change_handle { payload, .. }) => Some(capacity_stable_weights::SubstrateWeight::<Runtime>::change_handle(payload.base_handle.len() as u32)),
_ => None,
}
}
fn get_inner_calls(outer_call: &RuntimeCall) -> Option<Vec<&RuntimeCall>> {
match outer_call {
RuntimeCall::FrequencyTxPayment(FrequencyPaymentCall::pay_with_capacity {
call,
..
}) => return Some(vec![call]),
RuntimeCall::FrequencyTxPayment(
FrequencyPaymentCall::pay_with_capacity_batch_all { calls, .. },
) => return Some(calls.iter().collect()),
_ => Some(vec![outer_call]),
}
}
}
impl pallet_frequency_tx_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Capacity = Capacity;
type WeightInfo = pallet_frequency_tx_payment::weights::SubstrateWeight<Runtime>;
type CapacityCalls = CapacityEligibleCalls;
type OnChargeCapacityTransaction = pallet_frequency_tx_payment::CapacityAdapter<Balances, Msa>;
type BatchProvider = CapacityBatchProvider;
type MaximumCapacityBatchLength = MaximumCapacityBatchLength;
}
#[cfg(any(not(feature = "frequency"), feature = "frequency-lint-check"))]
impl pallet_passkey::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type WeightInfo = pallet_passkey::weights::SubstrateWeight<Runtime>;
type ConvertIntoAccountId32 = ConvertInto;
type PasskeyCallFilter = PasskeyCallFilter;
#[cfg(feature = "runtime-benchmarks")]
type Currency = Balances;
}
#[cfg(any(
feature = "frequency",
feature = "runtime-benchmarks",
feature = "frequency-lint-check",
))]
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1;
#[cfg(any(feature = "frequency-testnet", feature = "frequency-local"))]
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
const BLOCK_PROCESSING_VELOCITY: u32 = 1;
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6_000;
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
impl cumulus_pallet_parachain_system::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnSystemEvent = ();
type SelfParaId = parachain_info::Pallet<Runtime>;
type DmpQueue = frame_support::traits::EnqueueWithOrigin<(), sp_core::ConstU8<0>>;
type ReservedDmpWeight = ();
type OutboundXcmpMessageSource = ();
type XcmpMessageHandler = ();
type ReservedXcmpWeight = ();
type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
type WeightInfo = ();
type ConsensusHook = ConsensusHook;
}
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
pub type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
Runtime,
RELAY_CHAIN_SLOT_DURATION_MILLIS,
BLOCK_PROCESSING_VELOCITY,
UNINCLUDED_SEGMENT_CAPACITY,
>;
impl parachain_info::Config for Runtime {}
impl cumulus_pallet_aura_ext::Config for Runtime {}
impl pallet_session::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ValidatorId = <Self as frame_system::Config>::AccountId;
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
type SessionManager = CollatorSelection;
type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys;
type WeightInfo = weights::pallet_session::SubstrateWeight<Runtime>;
}
impl pallet_aura::Config for Runtime {
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = AuraMaxAuthorities;
type AllowMultipleBlocksPerSlot = ConstBool<{ prod_or_testnet_or_local!(false, true, true) }>;
type SlotDuration = ConstU64<SLOT_DURATION>;
}
impl pallet_collator_selection::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type UpdateOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 5>,
>;
type PotId = NeverDepositIntoId;
type MaxCandidates = CollatorMaxCandidates;
type MinEligibleCollators = CollatorMinCandidates;
type MaxInvulnerables = CollatorMaxInvulnerables;
type KickThreshold = CollatorKickThreshold;
type ValidatorId = <Self as frame_system::Config>::AccountId;
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
type ValidatorRegistration = Session;
type WeightInfo = weights::pallet_collator_selection::SubstrateWeight<Runtime>;
}
impl pallet_proxy::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type ProxyType = ProxyType;
type ProxyDepositBase = ProxyDepositBase;
type ProxyDepositFactor = ProxyDepositFactor;
type MaxProxies = MaxProxies;
type MaxPending = MaxPending;
type CallHasher = BlakeTwo256;
type AnnouncementDepositBase = AnnouncementDepositBase;
type AnnouncementDepositFactor = AnnouncementDepositFactor;
type WeightInfo = weights::pallet_proxy::SubstrateWeight<Runtime>;
}
impl pallet_messages::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_messages::weights::SubstrateWeight<Runtime>;
type MsaInfoProvider = Msa;
type SchemaGrantValidator = Msa;
type SchemaProvider = Schemas;
type MessagesMaxPayloadSizeBytes = MessagesMaxPayloadSizeBytes;
#[cfg(feature = "runtime-benchmarks")]
type MsaBenchmarkHelper = Msa;
#[cfg(feature = "runtime-benchmarks")]
type SchemaBenchmarkHelper = Schemas;
}
impl pallet_stateful_storage::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_stateful_storage::weights::SubstrateWeight<Runtime>;
type MaxItemizedPageSizeBytes = MaxItemizedPageSizeBytes;
type MaxPaginatedPageSizeBytes = MaxPaginatedPageSizeBytes;
type MaxItemizedBlobSizeBytes = MaxItemizedBlobSizeBytes;
type MaxPaginatedPageId = MaxPaginatedPageId;
type MaxItemizedActionsCount = MaxItemizedActionsCount;
type MsaInfoProvider = Msa;
type SchemaGrantValidator = Msa;
type SchemaProvider = Schemas;
type KeyHasher = Twox128;
type ConvertIntoAccountId32 = ConvertInto;
type MortalityWindowSize = StatefulMortalityWindowSize;
#[cfg(feature = "runtime-benchmarks")]
type MsaBenchmarkHelper = Msa;
#[cfg(feature = "runtime-benchmarks")]
type SchemaBenchmarkHelper = Schemas;
}
impl pallet_handles::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_handles::weights::SubstrateWeight<Runtime>;
type MsaInfoProvider = Msa;
type HandleSuffixMin = HandleSuffixMin;
type HandleSuffixMax = HandleSuffixMax;
type ConvertIntoAccountId32 = ConvertInto;
type MortalityWindowSize = MSAMortalityWindowSize;
#[cfg(feature = "runtime-benchmarks")]
type MsaBenchmarkHelper = Msa;
}
#[cfg(any(not(feature = "frequency"), feature = "frequency-lint-check"))]
impl pallet_sudo::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
}
impl pallet_utility::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type PalletsOrigin = OriginCaller;
type WeightInfo = weights::pallet_utility::SubstrateWeight<Runtime>;
}
construct_runtime!(
pub enum Runtime {
System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>} = 0,
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
ParachainSystem: cumulus_pallet_parachain_system::{
Pallet, Call, Config<T>, Storage, Inherent, Event<T>, ValidateUnsigned,
} = 1,
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2,
ParachainInfo: parachain_info::{Pallet, Storage, Config<T>} = 3,
#[cfg(any(not(feature = "frequency"), feature = "frequency-lint-check"))]
Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T> }= 4,
Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>, HoldReason} = 5,
Democracy: pallet_democracy::{Pallet, Call, Config<T>, Storage, Event<T> } = 6,
Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T> } = 8,
Utility: pallet_utility::{Pallet, Call, Event} = 9,
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 10,
TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>} = 11,
Council: pallet_collective::<Instance1>::{Pallet, Call, Config<T,I>, Storage, Event<T>, Origin<T>} = 12,
TechnicalCommittee: pallet_collective::<Instance2>::{Pallet, Call, Config<T,I>, Storage, Event<T>, Origin<T>} = 13,
Treasury: pallet_treasury::{Pallet, Call, Storage, Config<T>, Event<T>} = 14,
Authorship: pallet_authorship::{Pallet, 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<T>} = 24,
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 30,
TimeRelease: pallet_time_release::{Pallet, Call, Storage, Event<T>, Config<T>, FreezeReason} = 40,
Proxy: pallet_proxy = 43,
Msa: pallet_msa::{Pallet, Call, Storage, Event<T>} = 60,
Messages: pallet_messages::{Pallet, Call, Storage, Event<T>} = 61,
Schemas: pallet_schemas::{Pallet, Call, Storage, Event<T>, Config<T>} = 62,
StatefulStorage: pallet_stateful_storage::{Pallet, Call, Storage, Event<T>} = 63,
Capacity: pallet_capacity::{Pallet, Call, Storage, Event<T>, FreezeReason} = 64,
FrequencyTxPayment: pallet_frequency_tx_payment::{Pallet, Call, Event<T>} = 65,
Handles: pallet_handles::{Pallet, Call, Storage, Event<T>} = 66,
#[cfg(any(not(feature = "frequency"), feature = "frequency-lint-check"))]
Passkey: pallet_passkey::{Pallet, Call, Storage, Event<T>, ValidateUnsigned} = 67,
}
);
#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
pub struct StaleHashCheckExtension;
struct HashCheckData {
message_source_id: MessageSourceId,
schema_id: SchemaId,
page: Option<PageId>,
hash: PageHash,
}
impl HashCheckData {
fn new_itemized(
message_source_id: MessageSourceId,
schema_id: SchemaId,
hash: PageHash,
) -> Self {
Self { message_source_id, schema_id, page: None, hash }
}
fn new_paginated(
message_source_id: MessageSourceId,
schema_id: SchemaId,
page_id: PageId,
hash: PageHash,
) -> Self {
Self { message_source_id, schema_id, page: Some(page_id), hash }
}
}
impl sp_std::fmt::Debug for StaleHashCheckExtension {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
write!(f, "StaleHashCheckExtension")
}
#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}
impl SignedExtension for StaleHashCheckExtension {
const IDENTIFIER: &'static str = "StaleHashCheckExtension";
type AccountId = AccountId;
type Call = RuntimeCall;
type AdditionalSigned = ();
type Pre = ();
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
Ok(())
}
fn validate(
&self,
_who: &Self::AccountId,
call: &Self::Call,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
let mut valid_tx = ValidTransaction::default();
for trx in Self::extract_hash_data(call) {
match trx.page {
Some(page_id) => {
let r = Self::verify_hash_paginated(
&trx.message_source_id,
&trx.schema_id,
&page_id,
&trx.hash,
);
valid_tx = valid_tx.combine_with(r?);
},
None => {
let r = Self::verify_hash_itemized(
&trx.message_source_id,
&trx.schema_id,
&trx.hash,
);
valid_tx = valid_tx.combine_with(r?);
},
}
}
Ok(valid_tx)
}
fn pre_dispatch(
self,
_who: &Self::AccountId,
_call: &Self::Call,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Ok(())
}
}
impl StaleHashCheckExtension {
fn extract_hash_data(call: &RuntimeCall) -> Vec<HashCheckData> {
match call {
RuntimeCall::StatefulStorage(StatefulStorageCall::apply_item_actions {
state_owner_msa_id,
schema_id,
target_hash,
..
}) => vec![HashCheckData::new_itemized(*state_owner_msa_id, *schema_id, *target_hash)],
RuntimeCall::StatefulStorage(StatefulStorageCall::upsert_page {
state_owner_msa_id,
schema_id,
target_hash,
page_id,
..
}) |
RuntimeCall::StatefulStorage(StatefulStorageCall::delete_page {
state_owner_msa_id,
schema_id,
target_hash,
page_id,
..
}) => vec![HashCheckData::new_paginated(
*state_owner_msa_id,
*schema_id,
*page_id,
*target_hash,
)],
RuntimeCall::StatefulStorage(
StatefulStorageCall::apply_item_actions_with_signature { payload, .. },
) => vec![HashCheckData::new_itemized(
payload.msa_id,
payload.schema_id,
payload.target_hash,
)],
RuntimeCall::StatefulStorage(StatefulStorageCall::upsert_page_with_signature {
payload,
..
}) => vec![HashCheckData::new_paginated(
payload.msa_id,
payload.schema_id,
payload.page_id,
payload.target_hash,
)],
RuntimeCall::StatefulStorage(StatefulStorageCall::delete_page_with_signature {
payload,
..
}) => vec![HashCheckData::new_paginated(
payload.msa_id,
payload.schema_id,
payload.page_id,
payload.target_hash,
)],
RuntimeCall::StatefulStorage(
StatefulStorageCall::apply_item_actions_with_signature_v2 {
payload,
delegator_key,
..
},
) => match Msa::ensure_valid_msa_key(delegator_key) {
Ok(state_owner_msa_id) => vec![HashCheckData::new_itemized(
state_owner_msa_id,
payload.schema_id,
payload.target_hash,
)],
_ => vec![],
},
RuntimeCall::StatefulStorage(StatefulStorageCall::upsert_page_with_signature_v2 {
payload,
delegator_key,
..
}) => match Msa::ensure_valid_msa_key(delegator_key) {
Ok(state_owner_msa_id) => vec![HashCheckData::new_paginated(
state_owner_msa_id,
payload.schema_id,
payload.page_id,
payload.target_hash,
)],
_ => vec![],
},
RuntimeCall::StatefulStorage(StatefulStorageCall::delete_page_with_signature_v2 {
payload,
delegator_key,
..
}) => match Msa::ensure_valid_msa_key(delegator_key) {
Ok(state_owner_msa_id) => vec![HashCheckData::new_paginated(
state_owner_msa_id,
payload.schema_id,
payload.page_id,
payload.target_hash,
)],
_ => vec![],
},
RuntimeCall::FrequencyTxPayment(FrequencyPaymentCall::pay_with_capacity {
call,
..
}) => Self::extract_hash_data(call),
RuntimeCall::FrequencyTxPayment(
FrequencyPaymentCall::pay_with_capacity_batch_all { calls, .. },
) => calls.iter().flat_map(|c| Self::extract_hash_data(c)).collect(),
RuntimeCall::Utility(UtilityCall::batch { calls, .. }) |
RuntimeCall::Utility(UtilityCall::batch_all { calls, .. }) =>
calls.iter().flat_map(|c| Self::extract_hash_data(c)).collect(),
_ => vec![],
}
}
fn verify_hash_itemized(
msa_id: &MessageSourceId,
schema_id: &SchemaId,
target_hash: &PageHash,
) -> TransactionValidity {
const TAG_PREFIX: &str = "StatefulStorageHashItemized";
if let Ok(Some(page)) = StatefulStorage::get_itemized_page_for(*msa_id, *schema_id) {
let current_hash: PageHash = page.get_hash();
ensure!(
¤t_hash == target_hash,
Self::map_dispatch_error(
pallet_stateful_storage::Error::<Runtime>::StalePageState.into()
)
);
return ValidTransaction::with_tag_prefix(TAG_PREFIX)
.and_provides((msa_id, schema_id))
.build();
}
Ok(Default::default())
}
fn verify_hash_paginated(
msa_id: &MessageSourceId,
schema_id: &SchemaId,
page_id: &PageId,
target_hash: &PageHash,
) -> TransactionValidity {
const TAG_PREFIX: &str = "StatefulStorageHashPaginated";
if let Ok(Some(page)) =
StatefulStorage::get_paginated_page_for(*msa_id, *schema_id, *page_id)
{
let current_hash: PageHash = page.get_hash();
ensure!(
¤t_hash == target_hash,
Self::map_dispatch_error(
pallet_stateful_storage::Error::<Runtime>::StalePageState.into()
)
);
return ValidTransaction::with_tag_prefix(TAG_PREFIX)
.and_provides((msa_id, schema_id, page_id))
.build();
}
Ok(Default::default())
}
fn map_dispatch_error(err: DispatchError) -> InvalidTransaction {
InvalidTransaction::Custom(match err {
DispatchError::Module(module_err) =>
<u32 as Decode>::decode(&mut module_err.error.as_slice())
.unwrap_or_default()
.try_into()
.unwrap_or_default(),
_ => 255u8,
})
}
}
#[cfg(feature = "runtime-benchmarks")]
#[macro_use]
extern crate frame_benchmarking;
#[cfg(feature = "runtime-benchmarks")]
mod benches {
define_benchmarks!(
[frame_system, SystemBench::<Runtime>]
[pallet_balances, Balances]
[pallet_collective, Council]
[pallet_collective, TechnicalCommittee]
[pallet_preimage, Preimage]
[pallet_democracy, Democracy]
[pallet_treasury, Treasury]
[pallet_scheduler, Scheduler]
[pallet_session, SessionBench::<Runtime>]
[pallet_timestamp, Timestamp]
[pallet_collator_selection, CollatorSelection]
[pallet_multisig, Multisig]
[pallet_utility, Utility]
[pallet_proxy, Proxy]
[pallet_msa, Msa]
[pallet_schemas, Schemas]
[pallet_messages, Messages]
[pallet_stateful_storage, StatefulStorage]
[pallet_handles, Handles]
[pallet_time_release, TimeRelease]
[pallet_capacity, Capacity]
[pallet_frequency_tx_payment, FrequencyTxPayment]
);
}
#[cfg(any(not(feature = "frequency-no-relay"), feature = "frequency-lint-check"))]
cumulus_pallet_parachain_system::register_validate_block! {
Runtime = Runtime,
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
}
#[cfg(test)]
mod tests {
use super::*;
use frame_support::traits::WhitelistedStorageKeys;
use sp_core::hexdisplay::HexDisplay;
use std::collections::HashSet;
#[test]
fn check_whitelist() {
let whitelist: HashSet<String> = dbg!(AllPalletsWithSystem::whitelisted_storage_keys()
.iter()
.map(|e| HexDisplay::from(&e.key).to_string())
.collect());
assert!(
whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac")
);
assert!(
whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")
);
assert!(
whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a")
);
assert!(
whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850")
);
assert!(
whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7")
);
}
}