mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 11:07:56 +00:00
2009821cde
* Remove use of trait Store from staking pallet * Remove use of trait Store from bounties pallet * Remove use of trait Store from collective pallet * Remove use of trait Store from babe pallet * Remove use of trait Store from assets pallet * Remove use of trait Store from grandpa pallet * Remove use of trait Store from balances pallet * Remove use of trait Store from authorship pallet * Remove use of trait Store from authority-discovery pallet * Remove use of trait Store from atomic-swap pallet * Remove use of trait Store from sudo pallet * Remove use of trait Store from scheduler pallet * Remove use of trait Store from scored-pool pallet * Remove use of trait Store from society pallet * Remove use of trait Store from lottery pallet * Remove use of trait Store from executive pallet * Remove use of trait Store from democracy pallet * Remove use of trait Store from elections-phragmen pallet * Remove use of trait Store from indices pallet * Remove use of trait Store from identity pallet * Remove use of trait Store from multisig pallet * Remove use of trait Store from merkle-mountain-range pallet * Remove use of trait Store from im-online pallet * Remove use of trait Store from membership pallet * Remove use of trait Store from nicks pallet * Remove use of trait Store from session pallet * Remove use of trait Store from transaction-payment pallet * Remove use of trait Store from utility pallet * Remove use of trait Store from child-bounties pallet * Remove use of trait Store from nis pallet * Remove use of trait Store from nfts pallet * Remove use of trait Store from conviction-voting pallet * Remove use of trait Store from treasury pallet * Remove use of trait Store from vesting pallet * Remove use of trait Store from preimage pallet * Remove use of trait Store from uniques pallet * Remove use of trait Store from ranked-collective pallet * Remove use of trait Store from beefy-mmr pallet * Remove use of trait Store from referenda pallet * Remove use of trait Store from whitelist pallet * Remove use of trait Store from alliance pallet * Remove use of trait Store from nomination-pools pallet * Remove use of trait Store from state-trie-migration pallet * Remove use of trait Store from message-queue pallet * Remove use of trait Store from root-offences pallet * Remove use of trait Store from root-testing pallet * Remove use of trait Store from timestamps pallet * Remove use of trait Store from system pallet * Remove use of trait Store from offences pallet * Remove use of trait Store from recovery pallet * Remove use of trait Store from node-authorization pallet * Remove use of trait Store from proxy pallet * Remove use of trait Store from benchmarking pallet * Remove use of trait Store from bags-list pallet * Add deprecated warning in store_trait * Change warning message * Run cargo fmt * Fix warning and update tests * Remove unnecessary allow deprecated * Remove use of trait Store * Fix mismatch in expected output * Minor update to warning message for deprecation of generate_store with Store trait attribute * Fixes as per review comments * Fixes as per review suggestions * Remove use of Store trait from core-fellowship pallet * Fix type in store_trait.rs * Fixes as pre review comment
250 lines
7.1 KiB
Rust
250 lines
7.1 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) 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.
|
|
|
|
//! # Whitelist Pallet
|
|
//!
|
|
//! - [`Config`]
|
|
//! - [`Call`]
|
|
//!
|
|
//! ## Overview
|
|
//!
|
|
//! Allow some configurable origin: [`Config::WhitelistOrigin`] to whitelist some hash of a call,
|
|
//! and allow another configurable origin: [`Config::DispatchWhitelistedOrigin`] to dispatch them
|
|
//! with the root origin.
|
|
//!
|
|
//! In the meantime the call corresponding to the hash must have been submitted to the pre-image
|
|
//! handler [`pallet::Config::Preimages`].
|
|
|
|
#![cfg_attr(not(feature = "std"), no_std)]
|
|
|
|
#[cfg(feature = "runtime-benchmarks")]
|
|
mod benchmarking;
|
|
#[cfg(test)]
|
|
mod mock;
|
|
#[cfg(test)]
|
|
mod tests;
|
|
pub mod weights;
|
|
pub use weights::WeightInfo;
|
|
|
|
use codec::{DecodeLimit, Encode, FullCodec};
|
|
use frame_support::{
|
|
dispatch::{GetDispatchInfo, PostDispatchInfo},
|
|
ensure,
|
|
traits::{Hash as PreimageHash, QueryPreimage, StorePreimage},
|
|
weights::Weight,
|
|
Hashable,
|
|
};
|
|
use scale_info::TypeInfo;
|
|
use sp_runtime::traits::Dispatchable;
|
|
use sp_std::prelude::*;
|
|
|
|
pub use pallet::*;
|
|
|
|
#[frame_support::pallet]
|
|
pub mod pallet {
|
|
use super::*;
|
|
use frame_support::pallet_prelude::*;
|
|
use frame_system::pallet_prelude::*;
|
|
|
|
#[pallet::config]
|
|
pub trait Config: frame_system::Config {
|
|
/// The overarching event type.
|
|
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
|
|
|
/// The overarching call type.
|
|
type RuntimeCall: IsType<<Self as frame_system::Config>::RuntimeCall>
|
|
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>
|
|
+ GetDispatchInfo
|
|
+ FullCodec
|
|
+ TypeInfo
|
|
+ From<frame_system::Call<Self>>
|
|
+ Parameter;
|
|
|
|
/// Required origin for whitelisting a call.
|
|
type WhitelistOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
|
|
|
/// Required origin for dispatching whitelisted call with root origin.
|
|
type DispatchWhitelistedOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
|
|
|
/// The handler of pre-images.
|
|
type Preimages: QueryPreimage + StorePreimage;
|
|
|
|
/// The weight information for this pallet.
|
|
type WeightInfo: WeightInfo;
|
|
}
|
|
|
|
#[pallet::pallet]
|
|
pub struct Pallet<T>(_);
|
|
|
|
#[pallet::event]
|
|
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
|
pub enum Event<T: Config> {
|
|
CallWhitelisted { call_hash: PreimageHash },
|
|
WhitelistedCallRemoved { call_hash: PreimageHash },
|
|
WhitelistedCallDispatched { call_hash: PreimageHash, result: DispatchResultWithPostInfo },
|
|
}
|
|
|
|
#[pallet::error]
|
|
pub enum Error<T> {
|
|
/// The preimage of the call hash could not be loaded.
|
|
UnavailablePreImage,
|
|
/// The call could not be decoded.
|
|
UndecodableCall,
|
|
/// The weight of the decoded call was higher than the witness.
|
|
InvalidCallWeightWitness,
|
|
/// The call was not whitelisted.
|
|
CallIsNotWhitelisted,
|
|
/// The call was already whitelisted; No-Op.
|
|
CallAlreadyWhitelisted,
|
|
}
|
|
|
|
#[pallet::storage]
|
|
pub type WhitelistedCall<T: Config> =
|
|
StorageMap<_, Twox64Concat, PreimageHash, (), OptionQuery>;
|
|
|
|
#[pallet::call]
|
|
impl<T: Config> Pallet<T> {
|
|
#[pallet::call_index(0)]
|
|
#[pallet::weight(T::WeightInfo::whitelist_call())]
|
|
pub fn whitelist_call(origin: OriginFor<T>, call_hash: PreimageHash) -> DispatchResult {
|
|
T::WhitelistOrigin::ensure_origin(origin)?;
|
|
|
|
ensure!(
|
|
!WhitelistedCall::<T>::contains_key(call_hash),
|
|
Error::<T>::CallAlreadyWhitelisted,
|
|
);
|
|
|
|
WhitelistedCall::<T>::insert(call_hash, ());
|
|
T::Preimages::request(&call_hash);
|
|
|
|
Self::deposit_event(Event::<T>::CallWhitelisted { call_hash });
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[pallet::call_index(1)]
|
|
#[pallet::weight(T::WeightInfo::remove_whitelisted_call())]
|
|
pub fn remove_whitelisted_call(
|
|
origin: OriginFor<T>,
|
|
call_hash: PreimageHash,
|
|
) -> DispatchResult {
|
|
T::WhitelistOrigin::ensure_origin(origin)?;
|
|
|
|
WhitelistedCall::<T>::take(call_hash).ok_or(Error::<T>::CallIsNotWhitelisted)?;
|
|
|
|
T::Preimages::unrequest(&call_hash);
|
|
|
|
Self::deposit_event(Event::<T>::WhitelistedCallRemoved { call_hash });
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[pallet::call_index(2)]
|
|
#[pallet::weight(
|
|
T::WeightInfo::dispatch_whitelisted_call(*call_encoded_len)
|
|
.saturating_add(*call_weight_witness)
|
|
)]
|
|
pub fn dispatch_whitelisted_call(
|
|
origin: OriginFor<T>,
|
|
call_hash: PreimageHash,
|
|
call_encoded_len: u32,
|
|
call_weight_witness: Weight,
|
|
) -> DispatchResultWithPostInfo {
|
|
T::DispatchWhitelistedOrigin::ensure_origin(origin)?;
|
|
|
|
ensure!(
|
|
WhitelistedCall::<T>::contains_key(call_hash),
|
|
Error::<T>::CallIsNotWhitelisted,
|
|
);
|
|
|
|
let call = T::Preimages::fetch(&call_hash, Some(call_encoded_len))
|
|
.map_err(|_| Error::<T>::UnavailablePreImage)?;
|
|
|
|
let call = <T as Config>::RuntimeCall::decode_all_with_depth_limit(
|
|
sp_api::MAX_EXTRINSIC_DEPTH,
|
|
&mut &call[..],
|
|
)
|
|
.map_err(|_| Error::<T>::UndecodableCall)?;
|
|
|
|
ensure!(
|
|
call.get_dispatch_info().weight.all_lte(call_weight_witness),
|
|
Error::<T>::InvalidCallWeightWitness
|
|
);
|
|
|
|
let actual_weight = Self::clean_and_dispatch(call_hash, call).map(|w| {
|
|
w.saturating_add(T::WeightInfo::dispatch_whitelisted_call(call_encoded_len))
|
|
});
|
|
|
|
Ok(actual_weight.into())
|
|
}
|
|
|
|
#[pallet::call_index(3)]
|
|
#[pallet::weight({
|
|
let call_weight = call.get_dispatch_info().weight;
|
|
let call_len = call.encoded_size() as u32;
|
|
|
|
T::WeightInfo::dispatch_whitelisted_call_with_preimage(call_len)
|
|
.saturating_add(call_weight)
|
|
})]
|
|
pub fn dispatch_whitelisted_call_with_preimage(
|
|
origin: OriginFor<T>,
|
|
call: Box<<T as Config>::RuntimeCall>,
|
|
) -> DispatchResultWithPostInfo {
|
|
T::DispatchWhitelistedOrigin::ensure_origin(origin)?;
|
|
|
|
let call_hash = call.blake2_256().into();
|
|
|
|
ensure!(
|
|
WhitelistedCall::<T>::contains_key(call_hash),
|
|
Error::<T>::CallIsNotWhitelisted,
|
|
);
|
|
|
|
let call_len = call.encoded_size() as u32;
|
|
let actual_weight = Self::clean_and_dispatch(call_hash, *call).map(|w| {
|
|
w.saturating_add(T::WeightInfo::dispatch_whitelisted_call_with_preimage(call_len))
|
|
});
|
|
|
|
Ok(actual_weight.into())
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Config> Pallet<T> {
|
|
/// Clean whitelisting/preimage and dispatch call.
|
|
///
|
|
/// Return the call actual weight of the dispatched call if there is some.
|
|
fn clean_and_dispatch(
|
|
call_hash: PreimageHash,
|
|
call: <T as Config>::RuntimeCall,
|
|
) -> Option<Weight> {
|
|
WhitelistedCall::<T>::remove(call_hash);
|
|
|
|
T::Preimages::unrequest(&call_hash);
|
|
|
|
let result = call.dispatch(frame_system::Origin::<T>::Root.into());
|
|
|
|
let call_actual_weight = match result {
|
|
Ok(call_post_info) => call_post_info.actual_weight,
|
|
Err(call_err) => call_err.post_info.actual_weight,
|
|
};
|
|
|
|
Self::deposit_event(Event::<T>::WhitelistedCallDispatched { call_hash, result });
|
|
|
|
call_actual_weight
|
|
}
|
|
}
|