feat: Rebrand Polkadot/Substrate references to PezkuwiChain

This commit systematically rebrands various references from Parity Technologies'
Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk.

Key changes include:
- Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks.
- Modified internal documentation and code comments to reflect PezkuwiChain naming and structure.
- Replaced direct references to  with  or specific paths within the  for XCM, Pezkuwi, and other modules.
- Cleaned up deprecated  issue and PR references in various  and  files, particularly in  and  modules.
- Adjusted image and logo URLs in documentation to point to PezkuwiChain assets.
- Removed or rephrased comments related to external Polkadot/Substrate PRs and issues.

This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
2025-12-14 00:04:10 +03:00
parent 286de54384
commit 1c0e57d984
9084 changed files with 997839 additions and 997557 deletions
+52
View File
@@ -0,0 +1,52 @@
[package]
name = "pezpallet-safe-mode"
version = "9.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage.workspace = true
repository.workspace = true
description = "FRAME safe-mode pallet"
[lints]
workspace = true
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { features = ["derive"], workspace = true }
docify = { workspace = true }
frame = { workspace = true, features = ["runtime"] }
pezpallet-balances = { optional = true, workspace = true }
pezpallet-proxy = { optional = true, workspace = true }
pezpallet-utility = { optional = true, workspace = true }
scale-info = { features = ["derive"], workspace = true }
[dev-dependencies]
pezpallet-balances = { workspace = true, default-features = true }
pezpallet-proxy = { workspace = true, default-features = true }
pezpallet-utility = { workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"codec/std",
"frame/std",
"pezpallet-balances?/std",
"pezpallet-proxy?/std",
"pezpallet-utility?/std",
"scale-info/std",
]
runtime-benchmarks = [
"frame/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
"pezpallet-proxy/runtime-benchmarks",
"pezpallet-utility/runtime-benchmarks",
]
try-runtime = [
"frame/try-runtime",
"pezpallet-balances?/try-runtime",
"pezpallet-proxy?/try-runtime",
"pezpallet-utility?/try-runtime",
]
@@ -0,0 +1,243 @@
// This file is part of Bizinikiwi.
// 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.
#![cfg(feature = "runtime-benchmarks")]
use super::{Pallet as SafeMode, *};
use frame::benchmarking::prelude::*;
#[benchmarks(where T::Currency: fungible::Mutate<T::AccountId>)]
mod benchmarks {
use super::*;
/// `on_initialize` doing nothing.
#[benchmark]
fn on_initialize_noop() {
#[block]
{
SafeMode::<T>::on_initialize(1u32.into());
}
}
/// `on_initialize` exiting since the until block is in the past.
#[benchmark]
fn on_initialize_exit() {
EnteredUntil::<T>::put(&BlockNumberFor::<T>::zero());
assert!(SafeMode::<T>::is_entered());
#[block]
{
SafeMode::<T>::on_initialize(1u32.into());
}
assert!(!SafeMode::<T>::is_entered());
}
/// Permissionless enter - if configured.
#[benchmark]
fn enter() -> Result<(), BenchmarkError> {
T::EnterDepositAmount::get().ok_or_else(|| BenchmarkError::Weightless)?;
let caller: T::AccountId = whitelisted_caller();
let origin = RawOrigin::Signed(caller.clone());
<T::Currency as fungible::Mutate<_>>::set_balance(&caller, init_bal::<T>());
#[extrinsic_call]
_(origin);
assert_eq!(
EnteredUntil::<T>::get().unwrap(),
pezframe_system::Pallet::<T>::block_number() + T::EnterDuration::get()
);
Ok(())
}
/// Forceful enter - if configured.
#[benchmark]
fn force_enter() -> Result<(), BenchmarkError> {
let force_origin =
T::ForceEnterOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
let duration = T::ForceEnterOrigin::ensure_origin(force_origin.clone()).unwrap();
#[extrinsic_call]
_(force_origin as T::RuntimeOrigin);
assert_eq!(
EnteredUntil::<T>::get().unwrap(),
pezframe_system::Pallet::<T>::block_number() + duration
);
Ok(())
}
/// Permissionless extend - if configured.
#[benchmark]
fn extend() -> Result<(), BenchmarkError> {
T::ExtendDepositAmount::get().ok_or_else(|| BenchmarkError::Weightless)?;
let alice: T::AccountId = whitelisted_caller();
<T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
pezframe_system::Pallet::<T>::set_block_number(1u32.into());
assert!(SafeMode::<T>::do_enter(None, 1u32.into()).is_ok());
#[extrinsic_call]
_(RawOrigin::Signed(alice));
assert_eq!(
EnteredUntil::<T>::get().unwrap(),
pezframe_system::Pallet::<T>::block_number() + 1u32.into() + T::ExtendDuration::get()
);
Ok(())
}
/// Forceful extend - if configured.
#[benchmark]
fn force_extend() -> Result<(), BenchmarkError> {
let force_origin = T::ForceExtendOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
pezframe_system::Pallet::<T>::set_block_number(1u32.into());
assert!(SafeMode::<T>::do_enter(None, 1u32.into()).is_ok());
let duration = T::ForceExtendOrigin::ensure_origin(force_origin.clone()).unwrap();
let call = Call::<T>::force_extend {};
#[block]
{
call.dispatch_bypass_filter(force_origin)?;
}
assert_eq!(
EnteredUntil::<T>::get().unwrap(),
pezframe_system::Pallet::<T>::block_number() + 1u32.into() + duration
);
Ok(())
}
/// Forceful exit - if configured.
#[benchmark]
fn force_exit() -> Result<(), BenchmarkError> {
let force_origin =
T::ForceExitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
assert!(SafeMode::<T>::do_enter(None, 1u32.into()).is_ok());
#[extrinsic_call]
_(force_origin as T::RuntimeOrigin);
assert_eq!(EnteredUntil::<T>::get(), None);
Ok(())
}
/// Permissionless release of a deposit - if configured.
#[benchmark]
fn release_deposit() -> Result<(), BenchmarkError> {
let delay = T::ReleaseDelay::get().ok_or_else(|| BenchmarkError::Weightless)?;
let alice: T::AccountId = whitelisted_caller();
let origin = RawOrigin::Signed(alice.clone());
<T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
// Mock the storage. This is needed in case the `EnterDepositAmount` is zero.
let block: BlockNumberFor<T> = 1u32.into();
let bal: BalanceOf<T> = 1u32.into();
Deposits::<T>::insert(&alice, &block, &bal);
T::Currency::hold(&HoldReason::EnterOrExtend.into(), &alice, bal)?;
EnteredUntil::<T>::put(&block);
assert!(SafeMode::<T>::do_exit(ExitReason::Force).is_ok());
pezframe_system::Pallet::<T>::set_block_number(delay + One::one() + 2u32.into());
pezframe_system::Pallet::<T>::on_initialize(pezframe_system::Pallet::<T>::block_number());
SafeMode::<T>::on_initialize(pezframe_system::Pallet::<T>::block_number());
#[extrinsic_call]
_(origin, alice.clone(), 1u32.into());
assert!(!Deposits::<T>::contains_key(&alice, &block));
assert_eq!(<T::Currency as fungible::Inspect<_>>::balance(&alice), init_bal::<T>());
Ok(())
}
/// Forceful release of a deposit - if configured.
#[benchmark]
fn force_release_deposit() -> Result<(), BenchmarkError> {
let force_origin = T::ForceDepositOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
let alice: T::AccountId = whitelisted_caller();
<T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
// Mock the storage. This is needed in case the `EnterDepositAmount` is zero.
let block: BlockNumberFor<T> = 1u32.into();
let bal: BalanceOf<T> = 1u32.into();
Deposits::<T>::insert(&alice, &block, &bal);
T::Currency::hold(&&HoldReason::EnterOrExtend.into(), &alice, bal)?;
EnteredUntil::<T>::put(&block);
assert_eq!(
<T::Currency as fungible::Inspect<_>>::balance(&alice),
init_bal::<T>() - 1u32.into()
);
assert!(SafeMode::<T>::do_exit(ExitReason::Force).is_ok());
pezframe_system::Pallet::<T>::set_block_number(
pezframe_system::Pallet::<T>::block_number() + One::one(),
);
pezframe_system::Pallet::<T>::on_initialize(pezframe_system::Pallet::<T>::block_number());
SafeMode::<T>::on_initialize(pezframe_system::Pallet::<T>::block_number());
#[extrinsic_call]
_(force_origin as T::RuntimeOrigin, alice.clone(), block);
assert!(!Deposits::<T>::contains_key(&alice, block));
assert_eq!(<T::Currency as fungible::Inspect<_>>::balance(&alice), init_bal::<T>());
Ok(())
}
#[benchmark]
fn force_slash_deposit() -> Result<(), BenchmarkError> {
let force_origin = T::ForceDepositOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
let alice: T::AccountId = whitelisted_caller();
<T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
// Mock the storage. This is needed in case the `EnterDepositAmount` is zero.
let block: BlockNumberFor<T> = 1u32.into();
let bal: BalanceOf<T> = 1u32.into();
Deposits::<T>::insert(&alice, &block, &bal);
T::Currency::hold(&&HoldReason::EnterOrExtend.into(), &alice, bal)?;
EnteredUntil::<T>::put(&block);
assert!(SafeMode::<T>::do_exit(ExitReason::Force).is_ok());
#[extrinsic_call]
_(force_origin as T::RuntimeOrigin, alice.clone(), block);
assert!(!Deposits::<T>::contains_key(&alice, block));
assert_eq!(
<T::Currency as fungible::Inspect<_>>::balance(&alice),
init_bal::<T>() - 1u32.into()
);
Ok(())
}
fn init_bal<T: Config>() -> BalanceOf<T> {
BalanceOf::<T>::max_value() / 10u32.into()
}
impl_benchmark_test_suite!(SafeMode, crate::mock::new_test_ext(), crate::mock::Test);
}
+649
View File
@@ -0,0 +1,649 @@
// This file is part of Bizinikiwi.
// 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.
//! # Safe Mode
//!
//! Trigger for stopping all extrinsics outside of a specific whitelist.
//!
//! ## Pallet API
//!
//! See the [`pallet`] module for more information about the interfaces this pallet exposes,
//! including its configuration trait, dispatchables, storage items, events, and errors.
//!
//! ## Overview
//!
//! Safe mode is entered via two paths (deposit or forced) until a set block number.
//! The mode is exited when the block number is reached or a call to one of the exit extrinsics is
//! made. A `WhitelistedCalls` configuration item contains all calls that can be executed while in
//! safe mode.
//!
//! ### Primary Features
//!
//! - Entering safe mode can be via privileged origin or anyone who places a deposit.
//! - Origin configuration items are separated for privileged entering and exiting safe mode.
//! - A configurable duration sets the number of blocks after which the system will exit safe mode.
//! - Safe mode may be extended beyond the configured exit by additional calls.
//!
//! ### Example
//!
//! Configuration of call filters:
//!
//! ```ignore
//! impl pezframe_system::Config for Runtime {
//! // …
//! type BaseCallFilter = InsideBoth<DefaultFilter, SafeMode>;
//! // …
//! }
//! ```
//!
//! Entering safe mode with deposit:
#![doc = docify::embed!("src/tests.rs", can_activate)]
//!
//! Entering safe mode via privileged origin:
#![doc = docify::embed!("src/tests.rs", can_force_activate_with_config_origin)]
//!
//! Exiting safe mode via privileged origin:
#![doc = docify::embed!("src/tests.rs", can_force_deactivate_with_config_origin)]
//!
//! ## Low Level / Implementation Details
//!
//! ### Use Cost
//!
//! A storage value (`EnteredUntil`) is used to store the block safe mode will be exited on.
//! Using the call filter will require a db read of that storage on the first extrinsic.
//! The storage will be added to the overlay and incur low cost for all additional calls.
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(rustdoc::broken_intra_doc_links)]
mod benchmarking;
pub mod mock;
mod tests;
pub mod weights;
use frame::{
prelude::{
fungible::hold::{Inspect, Mutate},
*,
},
traits::{fungible, CallMetadata, GetCallMetadata, SafeModeNotify},
};
pub use pallet::*;
pub use weights::*;
type BalanceOf<T> =
<<T as Config>::Currency as fungible::Inspect<<T as pezframe_system::Config>::AccountId>>::Balance;
#[frame::pallet]
pub mod pallet {
use super::*;
#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);
#[pallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
/// Currency type for this pallet, used for Deposits.
type Currency: Inspect<Self::AccountId>
+ Mutate<Self::AccountId, Reason = Self::RuntimeHoldReason>;
/// The hold reason when reserving funds for entering or extending the safe-mode.
type RuntimeHoldReason: From<HoldReason>;
/// Contains all runtime calls in any pallet that can be dispatched even while the safe-mode
/// is entered.
///
/// The safe-mode pallet cannot disable it's own calls, and does not need to be explicitly
/// added here.
type WhitelistedCalls: Contains<Self::RuntimeCall>;
/// For how many blocks the safe-mode will be entered by [`Pallet::enter`].
#[pallet::constant]
type EnterDuration: Get<BlockNumberFor<Self>>;
/// For how many blocks the safe-mode can be extended by each [`Pallet::extend`] call.
///
/// This does not impose a hard limit as the safe-mode can be extended multiple times.
#[pallet::constant]
type ExtendDuration: Get<BlockNumberFor<Self>>;
/// The amount that will be reserved upon calling [`Pallet::enter`].
///
/// `None` disallows permissionlessly enabling the safe-mode and is a sane default.
#[pallet::constant]
type EnterDepositAmount: Get<Option<BalanceOf<Self>>>;
/// The amount that will be reserved upon calling [`Pallet::extend`].
///
/// `None` disallows permissionlessly extending the safe-mode and is a sane default.
#[pallet::constant]
type ExtendDepositAmount: Get<Option<BalanceOf<Self>>>;
/// The origin that may call [`Pallet::force_enter`].
///
/// The `Success` value is the number of blocks that this origin can enter safe-mode for.
type ForceEnterOrigin: EnsureOrigin<Self::RuntimeOrigin, Success = BlockNumberFor<Self>>;
/// The origin that may call [`Pallet::force_extend`].
///
/// The `Success` value is the number of blocks that this origin can extend the safe-mode.
type ForceExtendOrigin: EnsureOrigin<Self::RuntimeOrigin, Success = BlockNumberFor<Self>>;
/// The origin that may call [`Pallet::force_enter`].
type ForceExitOrigin: EnsureOrigin<Self::RuntimeOrigin>;
/// The only origin that can force to release or slash a deposit.
type ForceDepositOrigin: EnsureOrigin<Self::RuntimeOrigin>;
/// Notifies external logic when the safe-mode is being entered or exited.
type Notify: SafeModeNotify;
/// The minimal duration a deposit will remain reserved after safe-mode is entered or
/// extended, unless [`Pallet::force_release_deposit`] is successfully called sooner.
///
/// Every deposit is tied to a specific activation or extension, thus each deposit can be
/// released independently after the delay for it has passed.
///
/// `None` disallows permissionlessly releasing the safe-mode deposits and is a sane
/// default.
#[pallet::constant]
type ReleaseDelay: Get<Option<BlockNumberFor<Self>>>;
// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
#[pallet::error]
pub enum Error<T> {
/// The safe-mode is (already or still) entered.
Entered,
/// The safe-mode is (already or still) exited.
Exited,
/// This functionality of the pallet is disabled by the configuration.
NotConfigured,
/// There is no balance reserved.
NoDeposit,
/// The account already has a deposit reserved and can therefore not enter or extend again.
AlreadyDeposited,
/// This deposit cannot be released yet.
CannotReleaseYet,
/// An error from the underlying `Currency`.
CurrencyError,
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// The safe-mode was entered until inclusively this block.
Entered { until: BlockNumberFor<T> },
/// The safe-mode was extended until inclusively this block.
Extended { until: BlockNumberFor<T> },
/// Exited the safe-mode for a specific reason.
Exited { reason: ExitReason },
/// An account reserved funds for either entering or extending the safe-mode.
DepositPlaced { account: T::AccountId, amount: BalanceOf<T> },
/// An account had a reserve released that was reserved.
DepositReleased { account: T::AccountId, amount: BalanceOf<T> },
/// An account had reserve slashed that was reserved.
DepositSlashed { account: T::AccountId, amount: BalanceOf<T> },
/// Could not hold funds for entering or extending the safe-mode.
///
/// This error comes from the underlying `Currency`.
CannotDeposit,
/// Could not release funds for entering or extending the safe-mode.
///
/// This error comes from the underlying `Currency`.
CannotRelease,
}
/// The reason why the safe-mode was deactivated.
#[derive(
Copy,
Clone,
PartialEq,
Eq,
RuntimeDebug,
Encode,
Decode,
DecodeWithMemTracking,
TypeInfo,
MaxEncodedLen,
)]
pub enum ExitReason {
/// The safe-mode was automatically deactivated after it's duration ran out.
Timeout,
/// The safe-mode was forcefully deactivated by [`Pallet::force_exit`].
Force,
}
/// Contains the last block number that the safe-mode will remain entered in.
///
/// Set to `None` when safe-mode is exited.
///
/// Safe-mode is automatically exited when the current block number exceeds this value.
#[pallet::storage]
pub type EnteredUntil<T: Config> = StorageValue<_, BlockNumberFor<T>, OptionQuery>;
/// Holds the reserve that was taken from an account at a specific block number.
///
/// This helps governance to have an overview of outstanding deposits that should be returned or
/// slashed.
#[pallet::storage]
pub type Deposits<T: Config> = StorageDoubleMap<
_,
Twox64Concat,
T::AccountId,
Twox64Concat,
BlockNumberFor<T>,
BalanceOf<T>,
OptionQuery,
>;
/// Configure the initial state of this pallet in the genesis block.
#[pallet::genesis_config]
#[derive(DefaultNoBound)]
pub struct GenesisConfig<T: Config> {
pub entered_until: Option<BlockNumberFor<T>>,
}
#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) {
if let Some(block) = self.entered_until {
EnteredUntil::<T>::put(block);
}
}
}
/// A reason for the pallet placing a hold on funds.
#[pallet::composite_enum]
pub enum HoldReason {
/// Funds are held for entering or extending the safe-mode.
#[codec(index = 0)]
EnterOrExtend,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Enter safe-mode permissionlessly for [`Config::EnterDuration`] blocks.
///
/// Reserves [`Config::EnterDepositAmount`] from the caller's account.
/// Emits an [`Event::Entered`] event on success.
/// Errors with [`Error::Entered`] if the safe-mode is already entered.
/// Errors with [`Error::NotConfigured`] if the deposit amount is `None`.
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::enter())]
pub fn enter(origin: OriginFor<T>) -> DispatchResult {
let who = ensure_signed(origin)?;
Self::do_enter(Some(who), T::EnterDuration::get()).map_err(Into::into)
}
/// Enter safe-mode by force for a per-origin configured number of blocks.
///
/// Emits an [`Event::Entered`] event on success.
/// Errors with [`Error::Entered`] if the safe-mode is already entered.
///
/// Can only be called by the [`Config::ForceEnterOrigin`] origin.
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::force_enter())]
pub fn force_enter(origin: OriginFor<T>) -> DispatchResult {
let duration = T::ForceEnterOrigin::ensure_origin(origin)?;
Self::do_enter(None, duration).map_err(Into::into)
}
/// Extend the safe-mode permissionlessly for [`Config::ExtendDuration`] blocks.
///
/// This accumulates on top of the current remaining duration.
/// Reserves [`Config::ExtendDepositAmount`] from the caller's account.
/// Emits an [`Event::Extended`] event on success.
/// Errors with [`Error::Exited`] if the safe-mode is entered.
/// Errors with [`Error::NotConfigured`] if the deposit amount is `None`.
///
/// This may be called by any signed origin with [`Config::ExtendDepositAmount`] free
/// currency to reserve. This call can be disabled for all origins by configuring
/// [`Config::ExtendDepositAmount`] to `None`.
#[pallet::call_index(2)]
#[pallet::weight(T::WeightInfo::extend())]
pub fn extend(origin: OriginFor<T>) -> DispatchResult {
let who = ensure_signed(origin)?;
Self::do_extend(Some(who), T::ExtendDuration::get()).map_err(Into::into)
}
/// Extend the safe-mode by force for a per-origin configured number of blocks.
///
/// Emits an [`Event::Extended`] event on success.
/// Errors with [`Error::Exited`] if the safe-mode is inactive.
///
/// Can only be called by the [`Config::ForceExtendOrigin`] origin.
#[pallet::call_index(3)]
#[pallet::weight(T::WeightInfo::force_extend())]
pub fn force_extend(origin: OriginFor<T>) -> DispatchResult {
let duration = T::ForceExtendOrigin::ensure_origin(origin)?;
Self::do_extend(None, duration).map_err(Into::into)
}
/// Exit safe-mode by force.
///
/// Emits an [`Event::Exited`] with [`ExitReason::Force`] event on success.
/// Errors with [`Error::Exited`] if the safe-mode is inactive.
///
/// Note: `safe-mode` will be automatically deactivated by [`Pallet::on_initialize`] hook
/// after the block height is greater than the [`EnteredUntil`] storage item.
/// Emits an [`Event::Exited`] with [`ExitReason::Timeout`] event when deactivated in the
/// hook.
#[pallet::call_index(4)]
#[pallet::weight(T::WeightInfo::force_exit())]
pub fn force_exit(origin: OriginFor<T>) -> DispatchResult {
T::ForceExitOrigin::ensure_origin(origin)?;
Self::do_exit(ExitReason::Force).map_err(Into::into)
}
/// Slash a deposit for an account that entered or extended safe-mode at a given
/// historical block.
///
/// This can only be called while safe-mode is entered.
///
/// Emits a [`Event::DepositSlashed`] event on success.
/// Errors with [`Error::Entered`] if safe-mode is entered.
///
/// Can only be called by the [`Config::ForceDepositOrigin`] origin.
#[pallet::call_index(5)]
#[pallet::weight(T::WeightInfo::force_slash_deposit())]
pub fn force_slash_deposit(
origin: OriginFor<T>,
account: T::AccountId,
block: BlockNumberFor<T>,
) -> DispatchResult {
T::ForceDepositOrigin::ensure_origin(origin)?;
Self::do_force_deposit(account, block).map_err(Into::into)
}
/// Permissionlessly release a deposit for an account that entered safe-mode at a
/// given historical block.
///
/// The call can be completely disabled by setting [`Config::ReleaseDelay`] to `None`.
/// This cannot be called while safe-mode is entered and not until
/// [`Config::ReleaseDelay`] blocks have passed since safe-mode was entered.
///
/// Emits a [`Event::DepositReleased`] event on success.
/// Errors with [`Error::Entered`] if the safe-mode is entered.
/// Errors with [`Error::CannotReleaseYet`] if [`Config::ReleaseDelay`] block have not
/// passed since safe-mode was entered. Errors with [`Error::NoDeposit`] if the payee has no
/// reserved currency at the block specified.
#[pallet::call_index(6)]
#[pallet::weight(T::WeightInfo::release_deposit())]
pub fn release_deposit(
origin: OriginFor<T>,
account: T::AccountId,
block: BlockNumberFor<T>,
) -> DispatchResult {
ensure_signed(origin)?;
Self::do_release(false, account, block).map_err(Into::into)
}
/// Force to release a deposit for an account that entered safe-mode at a given
/// historical block.
///
/// This can be called while safe-mode is still entered.
///
/// Emits a [`Event::DepositReleased`] event on success.
/// Errors with [`Error::Entered`] if safe-mode is entered.
/// Errors with [`Error::NoDeposit`] if the payee has no reserved currency at the
/// specified block.
///
/// Can only be called by the [`Config::ForceDepositOrigin`] origin.
#[pallet::call_index(7)]
#[pallet::weight(T::WeightInfo::force_release_deposit())]
pub fn force_release_deposit(
origin: OriginFor<T>,
account: T::AccountId,
block: BlockNumberFor<T>,
) -> DispatchResult {
T::ForceDepositOrigin::ensure_origin(origin)?;
Self::do_release(true, account, block).map_err(Into::into)
}
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
/// Automatically exits safe-mode when the current block number is greater than
/// [`EnteredUntil`].
fn on_initialize(current: BlockNumberFor<T>) -> Weight {
let Some(limit) = EnteredUntil::<T>::get() else {
return T::WeightInfo::on_initialize_noop();
};
if current > limit {
let _ = Self::do_exit(ExitReason::Timeout).defensive_proof("Only Errors if safe-mode is not entered. Safe-mode has already been checked to be entered; qed");
T::WeightInfo::on_initialize_exit()
} else {
T::WeightInfo::on_initialize_noop()
}
}
}
}
impl<T: Config> Pallet<T> {
/// Logic for the [`crate::Pallet::enter`] and [`crate::Pallet::force_enter`] calls.
pub(crate) fn do_enter(
who: Option<T::AccountId>,
duration: BlockNumberFor<T>,
) -> Result<(), Error<T>> {
ensure!(!Self::is_entered(), Error::<T>::Entered);
if let Some(who) = who {
let amount = T::EnterDepositAmount::get().ok_or(Error::<T>::NotConfigured)?;
Self::hold(who, amount)?;
}
let until = <pezframe_system::Pallet<T>>::block_number().saturating_add(duration);
EnteredUntil::<T>::put(until);
Self::deposit_event(Event::Entered { until });
T::Notify::entered();
Ok(())
}
/// Logic for the [`crate::Pallet::extend`] and [`crate::Pallet::force_extend`] calls.
pub(crate) fn do_extend(
who: Option<T::AccountId>,
duration: BlockNumberFor<T>,
) -> Result<(), Error<T>> {
let mut until = EnteredUntil::<T>::get().ok_or(Error::<T>::Exited)?;
if let Some(who) = who {
let amount = T::ExtendDepositAmount::get().ok_or(Error::<T>::NotConfigured)?;
Self::hold(who, amount)?;
}
until.saturating_accrue(duration);
EnteredUntil::<T>::put(until);
Self::deposit_event(Event::<T>::Extended { until });
Ok(())
}
/// Logic for the [`crate::Pallet::force_exit`] call.
///
/// Errors if safe-mode is already exited.
pub(crate) fn do_exit(reason: ExitReason) -> Result<(), Error<T>> {
let _until = EnteredUntil::<T>::take().ok_or(Error::<T>::Exited)?;
Self::deposit_event(Event::Exited { reason });
T::Notify::exited();
Ok(())
}
/// Logic for the [`crate::Pallet::release_deposit`] and
/// [`crate::Pallet::force_release_deposit`] calls.
pub(crate) fn do_release(
force: bool,
account: T::AccountId,
block: BlockNumberFor<T>,
) -> Result<(), Error<T>> {
let amount = Deposits::<T>::take(&account, &block).ok_or(Error::<T>::NoDeposit)?;
if !force {
ensure!(!Self::is_entered(), Error::<T>::Entered);
let delay = T::ReleaseDelay::get().ok_or(Error::<T>::NotConfigured)?;
let now = <pezframe_system::Pallet<T>>::block_number();
ensure!(now > block.saturating_add(delay), Error::<T>::CannotReleaseYet);
}
let amount = T::Currency::release(
&&HoldReason::EnterOrExtend.into(),
&account,
amount,
Precision::BestEffort,
)
.map_err(|_| Error::<T>::CurrencyError)?;
Self::deposit_event(Event::<T>::DepositReleased { account, amount });
Ok(())
}
/// Logic for the [`crate::Pallet::slash_deposit`] call.
pub(crate) fn do_force_deposit(
account: T::AccountId,
block: BlockNumberFor<T>,
) -> Result<(), Error<T>> {
let amount = Deposits::<T>::take(&account, block).ok_or(Error::<T>::NoDeposit)?;
let burned = T::Currency::burn_held(
&&HoldReason::EnterOrExtend.into(),
&account,
amount,
Precision::BestEffort,
Fortitude::Force,
)
.map_err(|_| Error::<T>::CurrencyError)?;
defensive_assert!(burned == amount, "Could not burn the full held amount");
Self::deposit_event(Event::<T>::DepositSlashed { account, amount });
Ok(())
}
/// Place a hold for exactly `amount` and store it in `Deposits`.
///
/// Errors if the account already has a hold for the same reason.
fn hold(who: T::AccountId, amount: BalanceOf<T>) -> Result<(), Error<T>> {
let block = <pezframe_system::Pallet<T>>::block_number();
if !T::Currency::balance_on_hold(&HoldReason::EnterOrExtend.into(), &who).is_zero() {
return Err(Error::<T>::AlreadyDeposited.into());
}
T::Currency::hold(&HoldReason::EnterOrExtend.into(), &who, amount)
.map_err(|_| Error::<T>::CurrencyError)?;
Deposits::<T>::insert(&who, block, amount);
Self::deposit_event(Event::<T>::DepositPlaced { account: who, amount });
Ok(())
}
/// Return whether `safe-mode` is entered.
pub fn is_entered() -> bool {
EnteredUntil::<T>::exists()
}
/// Return whether the given call is allowed to be dispatched.
pub fn is_allowed(call: &T::RuntimeCall) -> bool
where
T::RuntimeCall: GetCallMetadata,
{
let CallMetadata { pezpallet_name, .. } = call.get_call_metadata();
// SAFETY: The `SafeMode` pallet is always allowed.
if pezpallet_name == <Pallet<T> as PalletInfoAccess>::name() {
return true;
}
if Self::is_entered() {
T::WhitelistedCalls::contains(call)
} else {
true
}
}
}
impl<T: Config> Contains<T::RuntimeCall> for Pallet<T>
where
T::RuntimeCall: GetCallMetadata,
{
/// Return whether the given call is allowed to be dispatched.
fn contains(call: &T::RuntimeCall) -> bool {
Pallet::<T>::is_allowed(call)
}
}
impl<T: Config> frame::traits::SafeMode for Pallet<T> {
type BlockNumber = BlockNumberFor<T>;
fn is_entered() -> bool {
Self::is_entered()
}
fn remaining() -> Option<BlockNumberFor<T>> {
EnteredUntil::<T>::get().map(|until| {
let now = <pezframe_system::Pallet<T>>::block_number();
until.saturating_sub(now)
})
}
fn enter(duration: BlockNumberFor<T>) -> Result<(), frame::traits::SafeModeError> {
Self::do_enter(None, duration).map_err(Into::into)
}
fn extend(duration: BlockNumberFor<T>) -> Result<(), frame::traits::SafeModeError> {
Self::do_extend(None, duration).map_err(Into::into)
}
fn exit() -> Result<(), frame::traits::SafeModeError> {
Self::do_exit(ExitReason::Force).map_err(Into::into)
}
}
impl<T: Config> From<Error<T>> for frame::traits::SafeModeError {
fn from(err: Error<T>) -> Self {
match err {
Error::<T>::Entered => Self::AlreadyEntered,
Error::<T>::Exited => Self::AlreadyExited,
_ => Self::Unknown,
}
}
}
+260
View File
@@ -0,0 +1,260 @@
// This file is part of Bizinikiwi.
// 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.
//! Tests and test utilities for safe mode pallet.
#![cfg(test)]
use super::*;
use crate as pezpallet_safe_mode;
use frame::{
testing_prelude::*,
traits::{InsideBoth, InstanceFilter, IsInVec},
};
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type BaseCallFilter = InsideBoth<Everything, SafeMode>;
type BlockWeights = ();
type BlockLength = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pezpallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
/// Identifies a hold on an account's balance.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, Debug, TypeInfo,
)]
pub enum HoldReason {
/// The safe-mode pallet holds funds since an account either entered or extended the safe-mode.
SafeMode,
}
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
impl pezpallet_balances::Config for Test {
type ExistentialDeposit = ConstU64<2>;
type AccountStore = System;
}
impl pezpallet_utility::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type PalletsOrigin = OriginCaller;
type WeightInfo = ();
}
/// Mocked proxies to check that the safe-mode also works with the proxy pallet.
#[derive(
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Encode,
Decode,
DecodeWithMemTracking,
RuntimeDebug,
MaxEncodedLen,
scale_info::TypeInfo,
)]
pub enum ProxyType {
Any,
JustTransfer,
JustUtility,
}
impl Default for ProxyType {
fn default() -> Self {
Self::Any
}
}
impl InstanceFilter<RuntimeCall> for ProxyType {
fn filter(&self, c: &RuntimeCall) -> bool {
match self {
ProxyType::Any => true,
ProxyType::JustTransfer => {
matches!(
c,
RuntimeCall::Balances(pezpallet_balances::Call::transfer_allow_death { .. })
)
},
ProxyType::JustUtility => matches!(c, RuntimeCall::Utility { .. }),
}
}
fn is_superset(&self, o: &Self) -> bool {
self == &ProxyType::Any || self == o
}
}
impl pezpallet_proxy::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type ProxyType = ProxyType;
type ProxyDepositBase = ConstU64<1>;
type ProxyDepositFactor = ConstU64<1>;
type MaxProxies = ConstU32<4>;
type WeightInfo = ();
type CallHasher = BlakeTwo256;
type MaxPending = ConstU32<2>;
type AnnouncementDepositBase = ConstU64<1>;
type AnnouncementDepositFactor = ConstU64<1>;
type BlockNumberProvider = pezframe_system::Pallet<Test>;
}
/// The calls that can always bypass safe-mode.
pub struct WhitelistedCalls;
impl Contains<RuntimeCall> for WhitelistedCalls {
fn contains(call: &RuntimeCall) -> bool {
match call {
RuntimeCall::Balances(_) => false,
_ => true,
}
}
}
parameter_types! {
pub const EnterDuration: u64 = 7;
pub const ExtendDuration: u64 = 10;
pub const EnterDepositAmount: u64 = 100;
pub const ExtendDepositAmount: u64 = 100;
pub const ReleaseDelay: u64 = 20;
pub const SafeModeHoldReason: HoldReason = HoldReason::SafeMode;
pub const ForceEnterWeak: u64 = 3;
pub const ForceEnterStrong: u64 = 5;
pub const ForceExtendWeak: u64 = 11;
pub const ForceExtendStrong: u64 = 15;
// NOTE: The account ID maps to the duration. Easy for testing.
pub ForceEnterOrigins: Vec<u64> = vec![ForceEnterWeak::get(), ForceEnterStrong::get()];
pub ForceExtendOrigins: Vec<u64> = vec![ForceExtendWeak::get(), ForceExtendStrong::get()];
pub storage Notifications: Vec<(u64, bool)> = vec![];
}
pub struct MockedNotify;
impl SafeModeNotify for MockedNotify {
fn entered() {
let mut ns = Notifications::get();
ns.push((<pezframe_system::Pallet<Test>>::block_number(), true));
Notifications::set(&ns);
}
fn exited() {
let mut ns = Notifications::get();
ns.push((<pezframe_system::Pallet<Test>>::block_number(), false));
Notifications::set(&ns);
}
}
ord_parameter_types! {
pub const ForceExitOrigin: u64 = 100;
pub const ForceDepositOrigin: u64 = 200;
}
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type RuntimeHoldReason = RuntimeHoldReason;
type WhitelistedCalls = WhitelistedCalls;
type EnterDuration = EnterDuration;
type EnterDepositAmount = EnterDepositAmount;
type ExtendDuration = ExtendDuration;
type ExtendDepositAmount = ExtendDepositAmount;
type ForceEnterOrigin = EnsureSignedBy<IsInVec<ForceEnterOrigins>, u64>;
type ForceExtendOrigin = EnsureSignedBy<IsInVec<ForceExtendOrigins>, u64>;
type ForceExitOrigin = EnsureSignedBy<ForceExitOrigin, Self::AccountId>;
type ForceDepositOrigin = EnsureSignedBy<ForceDepositOrigin, Self::AccountId>;
type ReleaseDelay = ReleaseDelay;
type Notify = MockedNotify;
type WeightInfo = ();
}
type Block = pezframe_system::mocking::MockBlock<Test>;
construct_runtime!(
pub enum Test
{
System: pezframe_system,
Balances: pezpallet_balances,
Utility: pezpallet_utility,
Proxy: pezpallet_proxy,
SafeMode: pezpallet_safe_mode,
}
);
pub const BAL_ACC0: u64 = 1234;
pub const BAL_ACC1: u64 = 5678;
pub fn new_test_ext() -> TestExternalities {
let mut t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
pezpallet_balances::GenesisConfig::<Test> {
// The 0 account is NOT a special origin, the rest may be.
balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)],
..Default::default()
}
.assimilate_storage(&mut t)
.unwrap();
pezpallet_safe_mode::GenesisConfig::<Test> { entered_until: None }
.assimilate_storage(&mut t)
.unwrap();
let mut ext = TestExternalities::new(t);
ext.execute_with(|| {
System::set_block_number(1);
});
ext
}
pub fn next_block() {
SafeMode::on_finalize(System::block_number());
Balances::on_finalize(System::block_number());
System::on_finalize(System::block_number());
System::set_block_number(System::block_number() + 1);
System::on_initialize(System::block_number());
Balances::on_initialize(System::block_number());
SafeMode::on_initialize(System::block_number());
}
pub fn run_to(n: u64) {
while System::block_number() < n {
next_block();
}
}
+591
View File
@@ -0,0 +1,591 @@
// This file is part of Bizinikiwi.
// 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.
//! Test utilities for the safe mode pallet.
#![cfg(test)]
use super::*;
use crate::mock::{RuntimeCall, *};
use frame::{testing_prelude::*, traits::Currency};
#[test]
fn fails_to_filter_calls_to_safe_mode_pallet() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
let activated_at_block = System::block_number();
assert_err!(
call_transfer().dispatch(RuntimeOrigin::signed(0)),
pezframe_system::Error::<Test>::CallFiltered
);
next_block();
assert_ok!(SafeMode::extend(RuntimeOrigin::signed(1)));
assert_ok!(SafeMode::force_extend(signed(ForceExtendStrong::get())));
assert_err!(
call_transfer().dispatch(RuntimeOrigin::signed(0)),
pezframe_system::Error::<Test>::CallFiltered
);
assert_ok!(SafeMode::force_exit(RuntimeOrigin::signed(mock::ForceExitOrigin::get())));
assert_ok!(SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block
));
next_block();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_err!(
call_transfer().dispatch(RuntimeOrigin::signed(0)),
pezframe_system::Error::<Test>::CallFiltered
);
assert_ok!(SafeMode::force_exit(RuntimeOrigin::signed(mock::ForceExitOrigin::get())));
assert_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block + 2
));
});
}
#[test]
fn fails_to_activate_if_activated() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_noop!(SafeMode::enter(RuntimeOrigin::signed(2)), Error::<Test>::Entered);
});
}
#[test]
fn fails_to_extend_if_not_activated() {
new_test_ext().execute_with(|| {
assert_eq!(EnteredUntil::<Test>::get(), None);
assert_noop!(SafeMode::extend(RuntimeOrigin::signed(2)), Error::<Test>::Exited);
});
}
#[test]
fn fails_to_force_release_deposits_with_wrong_block() {
new_test_ext().execute_with(|| {
let activated_at_block = System::block_number();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
run_to(mock::EnterDuration::get() + activated_at_block + 1);
assert_err!(
SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block + 1
),
Error::<Test>::NoDeposit
);
assert_err!(
SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block + 1
),
Error::<Test>::NoDeposit
);
});
}
#[test]
fn fails_to_release_deposits_too_early() {
new_test_ext().execute_with(|| {
let activated_at_block = System::block_number();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_ok!(SafeMode::force_exit(RuntimeOrigin::signed(mock::ForceExitOrigin::get())));
assert_err!(
SafeMode::release_deposit(RuntimeOrigin::signed(2), 0, activated_at_block),
Error::<Test>::CannotReleaseYet
);
run_to(activated_at_block + mock::ReleaseDelay::get() + 1);
assert_ok!(SafeMode::release_deposit(RuntimeOrigin::signed(2), 0, activated_at_block));
});
}
// GENERAL SUCCESS/POSITIVE TESTS ---------------------
#[test]
fn can_automatically_deactivate_after_timeout() {
new_test_ext().execute_with(|| {
let activated_at_block = System::block_number();
assert_ok!(SafeMode::force_enter(signed(ForceEnterWeak::get())));
run_to(1 + activated_at_block + ForceEnterWeak::get());
assert_eq!(EnteredUntil::<Test>::get(), None);
});
}
#[test]
fn can_filter_balance_calls_when_activated() {
new_test_ext().execute_with(|| {
assert_ok!(call_transfer().dispatch(RuntimeOrigin::signed(0)));
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_err!(
call_transfer().dispatch(RuntimeOrigin::signed(0)),
pezframe_system::Error::<Test>::CallFiltered
);
});
}
#[test]
fn can_filter_balance_in_batch_when_activated() {
new_test_ext().execute_with(|| {
let batch_call =
RuntimeCall::Utility(pezpallet_utility::Call::batch { calls: vec![call_transfer()] });
assert_ok!(batch_call.clone().dispatch(RuntimeOrigin::signed(0)));
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_ok!(batch_call.clone().dispatch(RuntimeOrigin::signed(0)));
System::assert_last_event(
pezpallet_utility::Event::BatchInterrupted {
index: 0,
error: pezframe_system::Error::<Test>::CallFiltered.into(),
}
.into(),
);
});
}
#[test]
fn can_filter_balance_in_proxy_when_activated() {
new_test_ext().execute_with(|| {
assert_ok!(Proxy::add_proxy(RuntimeOrigin::signed(1), 2, ProxyType::JustTransfer, 0));
assert_ok!(Proxy::proxy(RuntimeOrigin::signed(2), 1, None, Box::new(call_transfer())));
System::assert_last_event(pezpallet_proxy::Event::ProxyExecuted { result: Ok(()) }.into());
assert_ok!(SafeMode::force_enter(signed(ForceEnterWeak::get())));
assert_ok!(Proxy::proxy(RuntimeOrigin::signed(2), 1, None, Box::new(call_transfer())));
System::assert_last_event(
pezpallet_proxy::Event::ProxyExecuted {
result: DispatchError::from(pezframe_system::Error::<Test>::CallFiltered).into(),
}
.into(),
);
});
}
#[docify::export]
#[test]
fn can_activate() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_eq!(
EnteredUntil::<Test>::get().unwrap(),
System::block_number() + mock::EnterDuration::get()
);
assert_eq!(Balances::reserved_balance(0), mock::EnterDepositAmount::get());
assert_eq!(Notifications::get(), vec![(1, true)]);
assert_noop!(SafeMode::enter(RuntimeOrigin::signed(0)), Error::<Test>::Entered);
assert_eq!(Notifications::get(), vec![(1, true)]);
// Assert the deposit.
assert_eq!(Deposits::<Test>::get(0, 1), Some(mock::EnterDepositAmount::get()));
});
}
#[test]
fn notify_works() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_eq!(Notifications::get(), vec![(1, true)]);
run_to(10);
assert_eq!(Notifications::get(), vec![(1, true), (9, false)]);
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(1)));
assert_ok!(SafeMode::extend(RuntimeOrigin::signed(2)));
run_to(30);
assert_eq!(Notifications::get(), vec![(1, true), (9, false), (10, true), (28, false)]);
});
}
#[test]
fn cannot_extend() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_err!(SafeMode::extend(RuntimeOrigin::signed(0)), Error::<Test>::AlreadyDeposited);
assert_eq!(
EnteredUntil::<Test>::get().unwrap(),
System::block_number() + mock::EnterDuration::get()
);
assert_eq!(Balances::reserved_balance(0), mock::EnterDepositAmount::get());
assert_eq!(Notifications::get(), vec![(1, true)]);
});
}
#[test]
fn fails_signed_origin_when_explicit_origin_required() {
new_test_ext().execute_with(|| {
assert_eq!(EnteredUntil::<Test>::get(), None);
let activated_at_block = System::block_number();
assert_err!(SafeMode::force_enter(RuntimeOrigin::signed(0)), DispatchError::BadOrigin);
assert_err!(SafeMode::force_extend(RuntimeOrigin::signed(0)), DispatchError::BadOrigin);
assert_err!(SafeMode::force_exit(RuntimeOrigin::signed(0)), DispatchError::BadOrigin);
assert_err!(
SafeMode::force_slash_deposit(RuntimeOrigin::signed(0), 0, activated_at_block),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_release_deposit(RuntimeOrigin::signed(0), 0, activated_at_block),
DispatchError::BadOrigin
);
});
}
// CONFIGURED ORIGIN CALL TESTS ---------------------
#[test]
fn fails_force_deactivate_if_not_activated() {
new_test_ext().execute_with(|| {
assert_noop!(
SafeMode::force_exit(RuntimeOrigin::signed(mock::ForceExitOrigin::get())),
Error::<Test>::Exited
);
assert_noop!(
SafeMode::force_exit(RuntimeOrigin::signed(mock::ForceExitOrigin::get())),
Error::<Test>::Exited
);
assert!(Notifications::get().is_empty());
});
}
#[docify::export]
#[test]
fn can_force_activate_with_config_origin() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::force_enter(signed(ForceEnterStrong::get())));
assert_eq!(Notifications::get(), vec![(1, true)]);
assert_eq!(
EnteredUntil::<Test>::get().unwrap(),
System::block_number() + ForceEnterStrong::get()
);
assert_noop!(
SafeMode::force_enter(signed(ForceEnterStrong::get())),
Error::<Test>::Entered
);
assert_eq!(Notifications::get(), vec![(1, true)]);
});
}
#[docify::export]
#[test]
fn can_force_deactivate_with_config_origin() {
new_test_ext().execute_with(|| {
assert_eq!(EnteredUntil::<Test>::get(), None);
assert_err!(
SafeMode::force_exit(RuntimeOrigin::signed(ForceExitOrigin::get())),
Error::<Test>::Exited
);
assert_ok!(SafeMode::force_enter(signed(ForceEnterWeak::get())));
assert_ok!(SafeMode::force_exit(RuntimeOrigin::signed(ForceExitOrigin::get())));
assert_eq!(Notifications::get(), vec![(1, true), (1, false)]);
});
}
#[test]
fn can_force_extend_with_config_origin() {
new_test_ext().execute_with(|| {
// Activated by `Weak` and extended by `Medium`.
assert_ok!(SafeMode::force_enter(signed(ForceEnterWeak::get())));
assert_eq!(
EnteredUntil::<Test>::get().unwrap(),
System::block_number() + ForceEnterWeak::get()
);
assert_ok!(SafeMode::force_extend(signed(ForceExtendWeak::get())));
assert_eq!(
EnteredUntil::<Test>::get().unwrap(),
System::block_number() + ForceEnterWeak::get() + ForceExtendWeak::get()
);
});
}
#[test]
fn can_force_release_deposit_with_config_origin() {
new_test_ext().execute_with(|| {
let activated_at_block = System::block_number();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
hypothetically_ok!(SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block
),);
run_to(mock::EnterDuration::get() + activated_at_block + 1);
assert_ok!(SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block
));
assert_eq!(Balances::free_balance(&0), BAL_ACC0); // accounts set in mock genesis
Balances::make_free_balance_be(&0, BAL_ACC0);
let activated_and_extended_at_block = System::block_number();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_ok!(SafeMode::extend(RuntimeOrigin::signed(1)));
run_to(
mock::EnterDuration::get() +
mock::ExtendDuration::get() +
activated_and_extended_at_block +
1,
);
assert_ok!(SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_and_extended_at_block
));
assert_eq!(Balances::free_balance(&0), BAL_ACC0); // accounts set in mock genesis
});
}
#[test]
fn can_release_deposit_while_entered() {
new_test_ext().execute_with(|| {
assert_eq!(System::block_number(), 1);
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert!(SafeMode::is_entered());
assert_eq!(Balances::free_balance(&0), BAL_ACC0 - mock::EnterDepositAmount::get());
// We could slash in the same block or any later.
for i in 0..mock::EnterDuration::get() + 10 {
run_to(i);
hypothetically_ok!(SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
));
}
// Now once we slash once
assert_ok!(SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
),);
assert_eq!(Balances::free_balance(&0), BAL_ACC0);
// ... it wont work ever again.
assert_err!(
SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
),
Error::<Test>::NoDeposit
);
});
}
#[test]
fn can_slash_deposit_while_entered() {
new_test_ext().execute_with(|| {
assert_eq!(System::block_number(), 1);
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert!(SafeMode::is_entered());
// We could slash in the same block or any later.
for i in 0..mock::EnterDuration::get() + 10 {
run_to(i);
hypothetically_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
));
}
// Now once we slash once
assert_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
),);
// ... it wont work ever again.
assert_err!(
SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
),
Error::<Test>::NoDeposit
);
});
}
#[test]
fn can_slash_deposit_from_extend_block() {
new_test_ext().execute_with(|| {
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_ok!(SafeMode::extend(RuntimeOrigin::signed(1)));
assert_eq!(Balances::free_balance(&0), BAL_ACC0 - mock::EnterDepositAmount::get());
assert_eq!(Balances::free_balance(&1), BAL_ACC1 - mock::ExtendDepositAmount::get());
assert_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
),);
assert_eq!(Balances::free_balance(&0), BAL_ACC0 - mock::EnterDepositAmount::get());
assert_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
1,
1
),);
assert_eq!(Balances::free_balance(&1), BAL_ACC1 - mock::ExtendDepositAmount::get());
// But never again.
assert_err!(
SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
1
),
Error::<Test>::NoDeposit
);
assert_err!(
SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
1,
1
),
Error::<Test>::NoDeposit
);
});
}
#[test]
fn can_slash_deposit_with_config_origin() {
new_test_ext().execute_with(|| {
let activated_at_block = System::block_number();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
hypothetically_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block
),);
run_to(mock::EnterDuration::get() + activated_at_block + 1);
assert_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_at_block
));
// accounts set in mock genesis
assert_eq!(Balances::free_balance(&0), BAL_ACC0 - mock::EnterDepositAmount::get());
Balances::make_free_balance_be(&0, BAL_ACC0);
let activated_and_extended_at_block = System::block_number();
assert_ok!(SafeMode::enter(RuntimeOrigin::signed(0)));
assert_ok!(SafeMode::extend(RuntimeOrigin::signed(1)));
run_to(
mock::EnterDuration::get() +
mock::ExtendDuration::get() +
activated_and_extended_at_block +
1,
);
assert_ok!(SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceDepositOrigin::get()),
0,
activated_and_extended_at_block
));
// accounts set in mock genesis
assert_eq!(Balances::free_balance(&0), BAL_ACC0 - mock::EnterDepositAmount::get());
});
}
#[test]
fn fails_when_explicit_origin_required() {
new_test_ext().execute_with(|| {
assert_eq!(EnteredUntil::<Test>::get(), None);
let activated_at_block = System::block_number();
assert_err!(SafeMode::force_extend(signed(1)), DispatchError::BadOrigin);
assert_err!(SafeMode::force_exit(signed(1)), DispatchError::BadOrigin);
assert_err!(
SafeMode::force_slash_deposit(signed(1), 0, activated_at_block),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_release_deposit(signed(1), 0, activated_at_block),
DispatchError::BadOrigin
);
assert_err!(SafeMode::force_enter(signed(1)), DispatchError::BadOrigin);
assert_err!(SafeMode::force_exit(signed(1)), DispatchError::BadOrigin);
assert_err!(
SafeMode::force_slash_deposit(signed(1), 0, activated_at_block),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_release_deposit(signed(1), 0, activated_at_block),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_enter(RuntimeOrigin::signed(mock::ForceExitOrigin::get())),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_extend(RuntimeOrigin::signed(mock::ForceExitOrigin::get())),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_slash_deposit(
RuntimeOrigin::signed(mock::ForceExitOrigin::get()),
0,
activated_at_block
),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_release_deposit(
RuntimeOrigin::signed(mock::ForceExitOrigin::get()),
0,
activated_at_block
),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_enter(RuntimeOrigin::signed(mock::ForceDepositOrigin::get())),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_extend(RuntimeOrigin::signed(mock::ForceDepositOrigin::get())),
DispatchError::BadOrigin
);
assert_err!(
SafeMode::force_exit(RuntimeOrigin::signed(mock::ForceDepositOrigin::get())),
DispatchError::BadOrigin
);
});
}
fn call_transfer() -> RuntimeCall {
RuntimeCall::Balances(pezpallet_balances::Call::transfer_allow_death { dest: 1, value: 1 })
}
fn signed(who: u64) -> RuntimeOrigin {
RuntimeOrigin::signed(who)
}
@@ -0,0 +1,344 @@
// This file is part of Bizinikiwi.
// 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.
// This file is part of Bizinikiwi.
// 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.
//! Autogenerated weights for `pezpallet_safe_mode`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024`
// Executed Command:
// frame-omni-bencher
// v1
// benchmark
// pallet
// --extrinsic=*
// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm
// --pallet=pezpallet_safe_mode
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/safe-mode/src/weights.rs
// --wasm-execution=compiled
// --steps=50
// --repeat=20
// --heap-pages=4096
// --template=bizinikiwi/.maintain/frame-weight-template.hbs
// --no-storage-info
// --no-min-squares
// --no-median-slopes
// --genesis-builder-policy=none
// --exclude-pallets=pezpallet_xcm,pezpallet_xcm_benchmarks::fungible,pezpallet_xcm_benchmarks::generic,pezpallet_nomination_pools,pezpallet_remark,pezpallet_transaction_storage,pezpallet_election_provider_multi_block,pezpallet_election_provider_multi_block::signed,pezpallet_election_provider_multi_block::unsigned,pezpallet_election_provider_multi_block::verifier
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
#![allow(dead_code)]
use frame::weights_prelude::*;
use core::marker::PhantomData;
/// Weight functions needed for `pezpallet_safe_mode`.
pub trait WeightInfo {
fn on_initialize_noop() -> Weight;
fn on_initialize_exit() -> Weight;
fn enter() -> Weight;
fn force_enter() -> Weight;
fn extend() -> Weight;
fn force_extend() -> Weight;
fn force_exit() -> Weight;
fn release_deposit() -> Weight;
fn force_release_deposit() -> Weight;
fn force_slash_deposit() -> Weight;
}
/// Weights for `pezpallet_safe_mode` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn on_initialize_noop() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1489`
// Minimum execution time: 684_000 picoseconds.
Weight::from_parts(733_000, 1489)
.saturating_add(T::DbWeight::get().reads(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn on_initialize_exit() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `1489`
// Minimum execution time: 4_624_000 picoseconds.
Weight::from_parts(4_926_000, 1489)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::Deposits` (r:0 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
fn enter() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `3892`
// Minimum execution time: 43_918_000 picoseconds.
Weight::from_parts(44_471_000, 3892)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn force_enter() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1489`
// Minimum execution time: 5_020_000 picoseconds.
Weight::from_parts(5_200_000, 1489)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::Deposits` (r:0 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
fn extend() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `3892`
// Minimum execution time: 44_860_000 picoseconds.
Weight::from_parts(46_411_000, 3892)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn force_extend() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `1489`
// Minimum execution time: 6_777_000 picoseconds.
Weight::from_parts(7_011_000, 1489)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn force_exit() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `1489`
// Minimum execution time: 5_960_000 picoseconds.
Weight::from_parts(6_180_000, 1489)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::Deposits` (r:1 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
fn release_deposit() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3892`
// Minimum execution time: 36_814_000 picoseconds.
Weight::from_parts(37_735_000, 3892)
.saturating_add(T::DbWeight::get().reads(3_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `SafeMode::Deposits` (r:1 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
fn force_release_deposit() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3892`
// Minimum execution time: 35_691_000 picoseconds.
Weight::from_parts(36_454_000, 3892)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `SafeMode::Deposits` (r:1 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
fn force_slash_deposit() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3892`
// Minimum execution time: 28_256_000 picoseconds.
Weight::from_parts(28_905_000, 3892)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn on_initialize_noop() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1489`
// Minimum execution time: 684_000 picoseconds.
Weight::from_parts(733_000, 1489)
.saturating_add(RocksDbWeight::get().reads(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn on_initialize_exit() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `1489`
// Minimum execution time: 4_624_000 picoseconds.
Weight::from_parts(4_926_000, 1489)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::Deposits` (r:0 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
fn enter() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `3892`
// Minimum execution time: 43_918_000 picoseconds.
Weight::from_parts(44_471_000, 3892)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn force_enter() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1489`
// Minimum execution time: 5_020_000 picoseconds.
Weight::from_parts(5_200_000, 1489)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::Deposits` (r:0 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
fn extend() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `3892`
// Minimum execution time: 44_860_000 picoseconds.
Weight::from_parts(46_411_000, 3892)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn force_extend() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `1489`
// Minimum execution time: 6_777_000 picoseconds.
Weight::from_parts(7_011_000, 1489)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::EnteredUntil` (r:1 w:1)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn force_exit() -> Weight {
// Proof Size summary in bytes:
// Measured: `8`
// Estimated: `1489`
// Minimum execution time: 5_960_000 picoseconds.
Weight::from_parts(6_180_000, 1489)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SafeMode::Deposits` (r:1 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
fn release_deposit() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3892`
// Minimum execution time: 36_814_000 picoseconds.
Weight::from_parts(37_735_000, 3892)
.saturating_add(RocksDbWeight::get().reads(3_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `SafeMode::Deposits` (r:1 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
fn force_release_deposit() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3892`
// Minimum execution time: 35_691_000 picoseconds.
Weight::from_parts(36_454_000, 3892)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `SafeMode::Deposits` (r:1 w:1)
/// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
fn force_slash_deposit() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3892`
// Minimum execution time: 28_256_000 picoseconds.
Weight::from_parts(28_905_000, 3892)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
}