From 4525073154ffcf81255556ffa300f4c9d23b02d1 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 11 Aug 2023 09:35:14 +0300 Subject: [PATCH 01/69] Fork pallet-balances Signed-off-by: Georgi Zlatarev --- Cargo.lock | 69 +- pallets/asset-manager/Cargo.toml | 2 +- pallets/balances/Cargo.toml | 43 + pallets/balances/README.md | 122 ++ pallets/balances/src/benchmarking.rs | 222 +++ pallets/balances/src/lib.rs | 2209 ++++++++++++++++++++++ pallets/balances/src/migration.rs | 103 + pallets/balances/src/tests.rs | 1456 ++++++++++++++ pallets/balances/src/tests_composite.rs | 149 ++ pallets/balances/src/tests_local.rs | 191 ++ pallets/balances/src/tests_reentrancy.rs | 264 +++ pallets/balances/src/weights.rs | 164 ++ pallets/collator-selection/Cargo.toml | 2 +- pallets/farming/Cargo.toml | 4 +- pallets/manta-pay/Cargo.toml | 2 +- pallets/manta-sbt/Cargo.toml | 2 +- pallets/name-service/Cargo.toml | 2 +- pallets/pallet-lottery/Cargo.toml | 2 +- pallets/parachain-staking/Cargo.toml | 2 +- pallets/randomness/Cargo.toml | 2 +- pallets/tx-pause/Cargo.toml | 2 +- pallets/vesting/Cargo.toml | 4 +- runtime/calamari/Cargo.toml | 2 +- runtime/common/Cargo.toml | 2 +- runtime/integration-tests/Cargo.toml | 2 +- runtime/manta/Cargo.toml | 2 +- 26 files changed, 4983 insertions(+), 43 deletions(-) create mode 100644 pallets/balances/Cargo.toml create mode 100644 pallets/balances/README.md create mode 100644 pallets/balances/src/benchmarking.rs create mode 100644 pallets/balances/src/lib.rs create mode 100644 pallets/balances/src/migration.rs create mode 100644 pallets/balances/src/tests.rs create mode 100644 pallets/balances/src/tests_composite.rs create mode 100644 pallets/balances/src/tests_local.rs create mode 100644 pallets/balances/src/tests_reentrancy.rs create mode 100644 pallets/balances/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 533b3d9b0..9bdbc6e4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,7 +1129,7 @@ dependencies = [ "pallet-aura-style-filter", "pallet-author-inherent", "pallet-authorship", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-collective", "pallet-conviction-voting", "pallet-democracy", @@ -1204,7 +1204,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-timestamp", "parity-scale-codec", "scale-info", @@ -4193,7 +4193,7 @@ dependencies = [ "orml-xtokens", "pallet-asset-manager", "pallet-assets", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-collective", "pallet-democracy", "pallet-manta-pay", @@ -4498,7 +4498,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-bounties", "pallet-child-bounties", "pallet-collective", @@ -5416,7 +5416,7 @@ dependencies = [ "nimbus-primitives", "pallet-aura", "pallet-authorship", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-session", "pallet-timestamp", "parity-scale-codec", @@ -5545,7 +5545,7 @@ dependencies = [ "pallet-aura-style-filter", "pallet-author-inherent", "pallet-authorship", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-collective", "pallet-democracy", "pallet-farming", @@ -6503,7 +6503,7 @@ dependencies = [ "manta-primitives", "orml-traits", "pallet-assets", - "pallet-balances", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "sp-arithmetic", @@ -6646,7 +6646,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "sp-core", @@ -6656,6 +6656,23 @@ dependencies = [ "sp-tracing", ] +[[package]] +name = "pallet-balances" +version = "4.0.0-dev" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-transaction-payment", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-balances" version = "4.0.0-dev" @@ -6866,7 +6883,7 @@ dependencies = [ "orml-traits", "pallet-asset-manager", "pallet-assets", - "pallet-balances", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "sp-arithmetic", @@ -7011,7 +7028,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-parachain-staking", "pallet-preimage", "pallet-randomness", @@ -7052,7 +7069,7 @@ dependencies = [ "manta-util", "pallet-asset-manager", "pallet-assets", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-manta-support", "pallet-tx-pause", "parity-scale-codec", @@ -7088,7 +7105,7 @@ dependencies = [ "manta-util", "pallet-asset-manager", "pallet-assets", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-manta-pay", "pallet-manta-support", "pallet-timestamp", @@ -7190,7 +7207,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-manta-support", "parity-scale-codec", "safe-regex", @@ -7272,7 +7289,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "serde", @@ -7291,7 +7308,7 @@ dependencies = [ "frame-support", "frame-system", "pallet-babe", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-grandpa", "pallet-im-online", "pallet-offences", @@ -7314,7 +7331,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-session", "parity-scale-codec", "scale-info", @@ -7373,7 +7390,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", - "pallet-balances", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "serde", @@ -7668,7 +7685,7 @@ dependencies = [ "frame-support", "frame-system", "impl-trait-for-tuples", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "serde", @@ -7684,7 +7701,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "pallet-balances", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "sp-core", @@ -8881,7 +8898,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-bounties", "pallet-child-bounties", "pallet-collective", @@ -8966,7 +8983,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-beefy-mmr", "pallet-election-provider-multi-phase", "pallet-session", @@ -9039,7 +9056,7 @@ dependencies = [ "pallet-authority-discovery", "pallet-authorship", "pallet-babe", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-session", "pallet-staking", "pallet-timestamp", @@ -9905,7 +9922,7 @@ dependencies = [ "pallet-authority-discovery", "pallet-authorship", "pallet-babe", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", @@ -10066,7 +10083,7 @@ dependencies = [ "orml-xtokens", "pallet-asset-manager", "pallet-assets", - "pallet-balances", + "pallet-balances 4.0.0-dev", "pallet-transaction-payment", "pallet-utility", "pallet-xcm", @@ -14432,7 +14449,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "pallet-collective", "pallet-democracy", "pallet-election-provider-multi-phase", @@ -15025,7 +15042,7 @@ dependencies = [ "frame-system", "log", "orml-traits", - "pallet-balances", + "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "serde", diff --git a/pallets/asset-manager/Cargo.toml b/pallets/asset-manager/Cargo.toml index a9be6f607..d4b5a4c4d 100644 --- a/pallets/asset-manager/Cargo.toml +++ b/pallets/asset-manager/Cargo.toml @@ -25,7 +25,7 @@ orml-traits = { git = "https://github.com/manta-network/open-runtime-module-libr [dev-dependencies] pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml new file mode 100644 index 000000000..2ed128c00 --- /dev/null +++ b/pallets/balances/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "pallet-balances" +version = "4.0.0-dev" +authors = ["Parity Technologies "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://substrate.io" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME pallet to manage balances" +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } +log = { version = "0.4.17", default-features = false } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } +frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } + +[dev-dependencies] +pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "sp-runtime/std", + "sp-std/std", +] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/balances/README.md b/pallets/balances/README.md new file mode 100644 index 000000000..93e424a89 --- /dev/null +++ b/pallets/balances/README.md @@ -0,0 +1,122 @@ +# Balances Module + +The Balances module provides functionality for handling accounts and balances. + +- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) +- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) +- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) + +## Overview + +The Balances module provides functions for: + +- Getting and setting free balances. +- Retrieving total, reserved and unreserved balances. +- Repatriating a reserved balance to a beneficiary account that exists. +- Transferring a balance between accounts (when not reserved). +- Slashing an account balance. +- Account creation and removal. +- Managing total issuance. +- Setting and managing locks. + +### Terminology + +- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents +"dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) + fall below this, then the account is said to be dead; and it loses its functionality as well as any + prior history and all information on it is removed from the chain's state. + No account should ever have a total balance that is strictly between 0 and the existential + deposit (exclusive). If this ever happens, it indicates either a bug in this module or an + erroneous raw mutation of storage. + +- **Total Issuance:** The total number of units in existence in a system. + +- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its +total balance has become zero (or, strictly speaking, less than the Existential Deposit). + +- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only + balance that matters for most operations. + +- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. + Reserved balance can still be slashed, but only after all the free balance has been slashed. + +- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting +(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will +return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is +simply dropped, it should automatically maintain any book-keeping such as total issuance.) + +- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple +locks always operate over the same funds, so they "overlay" rather than "stack". + +### Implementations + +The Balances module provides implementations for the following traits. If these traits provide the functionality +that you need, then you can avoid coupling with the Balances module. + +- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing with a +fungible assets system. +- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): +Functions for dealing with assets that can be reserved from an account. +- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions for +dealing with accounts that allow liquidity restrictions. +- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling +imbalances between total issuance in the system and account balances. Must be used when a function +creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to say whether a +given account is unused. + +## Interface + +### Dispatchable Functions + +- `transfer` - Transfer some liquid free balance to another account. +- `set_balance` - Set the balances of a given account. The origin of this call must be root. + +## Usage + +The following examples show how to use the Balances module in your custom module. + +### Examples from the FRAME + +The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: + +```rust +use frame_support::traits::Currency; + +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; + +``` + +The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: + +```rust +use frame_support::traits::{WithdrawReasons, LockableCurrency}; +use sp_runtime::traits::Bounded; +pub trait Config: frame_system::Config { + type Currency: LockableCurrency; +} + +fn update_ledger( + controller: &T::AccountId, + ledger: &StakingLedger +) { + T::Currency::set_lock( + STAKING_ID, + &ledger.stash, + ledger.total, + WithdrawReasons::all() + ); + // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +} +``` + +## Genesis config + +The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). + +## Assumptions + +* Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. + +License: Apache-2.0 diff --git a/pallets/balances/src/benchmarking.rs b/pallets/balances/src/benchmarking.rs new file mode 100644 index 000000000..164d10d44 --- /dev/null +++ b/pallets/balances/src/benchmarking.rs @@ -0,0 +1,222 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2020-2022 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. + +// //! Balances pallet benchmarking. + +// #![cfg(feature = "runtime-benchmarks")] + +// use super::*; + +// use frame_benchmarking::{account, benchmarks_instance_pallet, whitelisted_caller}; +// use frame_system::RawOrigin; +// use sp_runtime::traits::Bounded; + +// use crate::Pallet as Balances; + +// const SEED: u32 = 0; +// // existential deposit multiplier +// const ED_MULTIPLIER: u32 = 10; + +// benchmarks_instance_pallet! { +// // Benchmark `transfer` extrinsic with the worst possible conditions: +// // * Transfer will kill the sender account. +// // * Transfer will create the recipient account. +// transfer { +// let existential_deposit = T::ExistentialDeposit::get(); +// let caller = whitelisted_caller(); + +// // Give some multiple of the existential deposit +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + +// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, +// // and reap this user. +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); +// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); +// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // Benchmark `transfer` with the best possible condition: +// // * Both accounts exist and will continue to exist. +// #[extra] +// transfer_best_case { +// let caller = whitelisted_caller(); +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + +// // Give the sender account max funds for transfer (their account will never reasonably be killed). +// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + +// // Give the recipient account existential deposit (thus their account already exists). +// let existential_deposit = T::ExistentialDeposit::get(); +// let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); +// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert!(!Balances::::free_balance(&caller).is_zero()); +// assert!(!Balances::::free_balance(&recipient).is_zero()); +// } + +// // Benchmark `transfer_keep_alive` with the worst possible condition: +// // * The recipient account is created. +// transfer_keep_alive { +// let caller = whitelisted_caller(); +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + +// // Give the sender account max funds, thus a transfer will not kill account. +// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); +// let existential_deposit = T::ExistentialDeposit::get(); +// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert!(!Balances::::free_balance(&caller).is_zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // Benchmark `set_balance` coming from ROOT account. This always creates an account. +// set_balance_creating { +// let user: T::AccountId = account("user", 0, SEED); +// let user_lookup = T::Lookup::unlookup(user.clone()); + +// // Give the user some initial balance. +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); +// }: set_balance(RawOrigin::Root, user_lookup, balance_amount, balance_amount) +// verify { +// assert_eq!(Balances::::free_balance(&user), balance_amount); +// assert_eq!(Balances::::reserved_balance(&user), balance_amount); +// } + +// // Benchmark `set_balance` coming from ROOT account. This always kills an account. +// set_balance_killing { +// let user: T::AccountId = account("user", 0, SEED); +// let user_lookup = T::Lookup::unlookup(user.clone()); + +// // Give the user some initial balance. +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); +// }: set_balance(RawOrigin::Root, user_lookup, Zero::zero(), Zero::zero()) +// verify { +// assert!(Balances::::free_balance(&user).is_zero()); +// } + +// // Benchmark `force_transfer` extrinsic with the worst possible conditions: +// // * Transfer will kill the sender account. +// // * Transfer will create the recipient account. +// force_transfer { +// let existential_deposit = T::ExistentialDeposit::get(); +// let source: T::AccountId = account("source", 0, SEED); +// let source_lookup = T::Lookup::unlookup(source.clone()); + +// // Give some multiple of the existential deposit +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&source, balance); + +// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); +// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); +// }: force_transfer(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount) +// verify { +// assert_eq!(Balances::::free_balance(&source), Zero::zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // This benchmark performs the same operation as `transfer` in the worst case scenario, +// // but additionally introduces many new users into the storage, increasing the the merkle +// // trie and PoV size. +// #[extra] +// transfer_increasing_users { +// // 1_000 is not very much, but this upper bound can be controlled by the CLI. +// let u in 0 .. 1_000; +// let existential_deposit = T::ExistentialDeposit::get(); +// let caller = whitelisted_caller(); + +// // Give some multiple of the existential deposit +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + +// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, +// // and reap this user. +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); +// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + +// // Create a bunch of users in storage. +// for i in 0 .. u { +// // The `account` function uses `blake2_256` to generate unique accounts, so these +// // should be quite random and evenly distributed in the trie. +// let new_user: T::AccountId = account("new_user", i, SEED); +// let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); +// } +// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // Benchmark `transfer_all` with the worst possible condition: +// // * The recipient account is created +// // * The sender is killed +// transfer_all { +// let caller = whitelisted_caller(); +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + +// // Give some multiple of the existential deposit +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); +// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, false) +// verify { +// assert!(Balances::::free_balance(&caller).is_zero()); +// assert_eq!(Balances::::free_balance(&recipient), balance); +// } + +// force_unreserve { +// let user: T::AccountId = account("user", 0, SEED); +// let user_lookup = T::Lookup::unlookup(user.clone()); + +// // Give some multiple of the existential deposit +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&user, balance); + +// // Reserve the balance +// as ReservableCurrency<_>>::reserve(&user, balance)?; +// assert_eq!(Balances::::reserved_balance(&user), balance); +// assert!(Balances::::free_balance(&user).is_zero()); + +// }: _(RawOrigin::Root, user_lookup, balance) +// verify { +// assert!(Balances::::reserved_balance(&user).is_zero()); +// assert_eq!(Balances::::free_balance(&user), balance); +// } + +// impl_benchmark_test_suite!( +// Balances, +// crate::tests_composite::ExtBuilder::default().build(), +// crate::tests_composite::Test, +// ) +// } diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs new file mode 100644 index 000000000..99d77a3e7 --- /dev/null +++ b/pallets/balances/src/lib.rs @@ -0,0 +1,2209 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2022 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. + +//! # Balances Pallet +//! +//! The Balances pallet provides functionality for handling accounts and balances. +//! +//! - [`Config`] +//! - [`Call`] +//! - [`Pallet`] +//! +//! ## Overview +//! +//! The Balances pallet provides functions for: +//! +//! - Getting and setting free balances. +//! - Retrieving total, reserved and unreserved balances. +//! - Repatriating a reserved balance to a beneficiary account that exists. +//! - Transferring a balance between accounts (when not reserved). +//! - Slashing an account balance. +//! - Account creation and removal. +//! - Managing total issuance. +//! - Setting and managing locks. +//! +//! ### Terminology +//! +//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This +//! prevents "dust accounts" from filling storage. When the free plus the reserved balance (i.e. +//! the total balance) fall below this, then the account is said to be dead; and it loses its +//! functionality as well as any prior history and all information on it is removed from the +//! chain's state. No account should ever have a total balance that is strictly between 0 and the +//! existential deposit (exclusive). If this ever happens, it indicates either a bug in this +//! pallet or an erroneous raw mutation of storage. +//! +//! - **Total Issuance:** The total number of units in existence in a system. +//! +//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after +//! its +//! total balance has become zero (or, strictly speaking, less than the Existential Deposit). +//! +//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only +//! balance that matters for most operations. +//! +//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. +//! Reserved balance can still be slashed, but only after all the free balance has been slashed. +//! +//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite +//! accounting +//! (i.e. a difference between total issuance and account balances). Functions that result in an +//! imbalance will return an object of the `Imbalance` trait that can be managed within your runtime +//! logic. (If an imbalance is simply dropped, it should automatically maintain any book-keeping +//! such as total issuance.) +//! +//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block +//! number. Multiple +//! locks always operate over the same funds, so they "overlay" rather than "stack". +//! +//! ### Implementations +//! +//! The Balances pallet provides implementations for the following traits. If these traits provide +//! the functionality that you need, then you can avoid coupling with the Balances pallet. +//! +//! - [`Currency`](frame_support::traits::Currency): Functions for dealing with a +//! fungible assets system. +//! - [`ReservableCurrency`](frame_support::traits::ReservableCurrency): +//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency): +//! Functions for dealing with assets that can be reserved from an account. +//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for +//! dealing with accounts that allow liquidity restrictions. +//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling +//! imbalances between total issuance in the system and account balances. Must be used when a +//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! - `transfer` - Transfer some liquid free balance to another account. +//! - `set_balance` - Set the balances of a given account. The origin of this call must be root. +//! +//! ## Usage +//! +//! The following examples show how to use the Balances pallet in your custom pallet. +//! +//! ### Examples from the FRAME +//! +//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from +//! `Currency`: +//! +//! ``` +//! use frame_support::traits::Currency; +//! # pub trait Config: frame_system::Config { +//! # type Currency: Currency; +//! # } +//! +//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +//! +//! # fn main() {} +//! ``` +//! +//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds: +//! +//! ``` +//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; +//! use sp_runtime::traits::Bounded; +//! pub trait Config: frame_system::Config { +//! type Currency: LockableCurrency; +//! } +//! # struct StakingLedger { +//! # stash: ::AccountId, +//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, +//! # phantom: std::marker::PhantomData, +//! # } +//! # const STAKING_ID: [u8; 8] = *b"staking "; +//! +//! fn update_ledger( +//! controller: &T::AccountId, +//! ledger: &StakingLedger +//! ) { +//! T::Currency::set_lock( +//! STAKING_ID, +//! &ledger.stash, +//! ledger.total, +//! WithdrawReasons::all() +//! ); +//! // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +//! } +//! # fn main() {} +//! ``` +//! +//! ## Genesis config +//! +//! The Balances pallet depends on the [`GenesisConfig`]. +//! +//! ## Assumptions +//! +//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[macro_use] +mod tests; +mod benchmarking; +pub mod migration; +mod tests_composite; +mod tests_local; +#[cfg(test)] +mod tests_reentrancy; +pub mod weights; + +pub use self::imbalances::{NegativeImbalance, PositiveImbalance}; +use codec::{Codec, Decode, Encode, MaxEncodedLen}; +#[cfg(feature = "std")] +use frame_support::traits::GenesisBuild; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{ + tokens::{fungible, BalanceStatus as Status, DepositConsequence, WithdrawConsequence}, + Currency, DefensiveSaturating, ExistenceRequirement, + ExistenceRequirement::{AllowDeath, KeepAlive}, + Get, Imbalance, LockIdentifier, LockableCurrency, NamedReservableCurrency, OnUnbalanced, + ReservableCurrency, SignedImbalance, StoredMap, TryDrop, WithdrawReasons, + }, + WeakBoundedVec, +}; +use frame_system as system; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{ + AtLeast32BitUnsigned, Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, + Saturating, StaticLookup, Zero, + }, + ArithmeticError, DispatchError, FixedPointOperand, RuntimeDebug, +}; +use sp_std::{cmp, fmt::Debug, mem, ops::BitOr, prelude::*, result}; +pub use weights::WeightInfo; + +pub use pallet::*; + +const LOG_TARGET: &str = "runtime::balances"; + +type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; + +#[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 balance of an account. + type Balance: Parameter + + Member + + AtLeast32BitUnsigned + + Codec + + Default + + Copy + + MaybeSerializeDeserialize + + Debug + + MaxEncodedLen + + TypeInfo + + FixedPointOperand; + + /// Handler for the unbalanced reduction when removing a dust account. + type DustRemoval: OnUnbalanced>; + + /// The overarching event type. + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + + /// The minimum amount required to keep an account open. + #[pallet::constant] + type ExistentialDeposit: Get; + + /// The means of storing the balances of an account. + type AccountStore: StoredMap>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// The maximum number of locks that should exist on an account. + /// Not strictly enforced, but used for weight estimation. + #[pallet::constant] + type MaxLocks: Get; + + /// The maximum number of named reserves that can exist on an account. + #[pallet::constant] + type MaxReserves: Get; + + /// The id type for named reserves. + type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; + } + + /// The current storage version. + const STORAGE_VERSION: frame_support::traits::StorageVersion = + frame_support::traits::StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::call] + impl, I: 'static> Pallet { + /// Transfer some liquid free balance to another account. + /// + /// `transfer` will set the `FreeBalance` of the sender and receiver. + /// If the sender's account is below the existential deposit as a result + /// of the transfer, the account will be reaped. + /// + /// The dispatch origin for this call must be `Signed` by the transactor. + /// + /// # + /// - Dependent on arguments but not critical, given proper implementations for input config + /// types. See related functions below. + /// - It contains a limited number of reads and writes internally and no complex + /// computation. + /// + /// Related functions: + /// + /// - `ensure_can_withdraw` is always called internally but has a bounded complexity. + /// - Transferring balances to accounts that did not exist before will cause + /// `T::OnNewAccount::on_new_account` to be called. + /// - Removing enough funds from an account will trigger `T::DustRemoval::on_unbalanced`. + /// - `transfer_keep_alive` works the same way as `transfer`, but has an additional check + /// that the transfer will not kill the origin account. + /// --------------------------------- + /// - Origin account is already in memory, so no DB operations for them. + /// # + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::transfer())] + pub fn transfer( + origin: OriginFor, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResultWithPostInfo { + let transactor = ensure_signed(origin)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer( + &transactor, + &dest, + value, + ExistenceRequirement::AllowDeath, + )?; + Ok(().into()) + } + + /// Set the balances of a given account. + /// + /// This will alter `FreeBalance` and `ReservedBalance` in storage. it will + /// also alter the total issuance of the system (`TotalIssuance`) appropriately. + /// If the new free or reserved balance is below the existential deposit, + /// it will reset the account nonce (`frame_system::AccountNonce`). + /// + /// The dispatch origin for this call is `root`. + #[pallet::call_index(1)] + #[pallet::weight( + T::WeightInfo::set_balance_creating() // Creates a new account. + .max(T::WeightInfo::set_balance_killing()) // Kills an existing account. + )] + pub fn set_balance( + origin: OriginFor, + who: AccountIdLookupOf, + #[pallet::compact] new_free: T::Balance, + #[pallet::compact] new_reserved: T::Balance, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + let existential_deposit = T::ExistentialDeposit::get(); + + let wipeout = new_free + new_reserved < existential_deposit; + let new_free = if wipeout { Zero::zero() } else { new_free }; + let new_reserved = if wipeout { Zero::zero() } else { new_reserved }; + + // First we try to modify the account's balance to the forced balance. + let (old_free, old_reserved) = Self::mutate_account(&who, |account| { + let old_free = account.free; + let old_reserved = account.reserved; + + account.free = new_free; + account.reserved = new_reserved; + + (old_free, old_reserved) + })?; + + // This will adjust the total issuance, which was not done by the `mutate_account` + // above. + if new_free > old_free { + mem::drop(PositiveImbalance::::new(new_free - old_free)); + } else if new_free < old_free { + mem::drop(NegativeImbalance::::new(old_free - new_free)); + } + + if new_reserved > old_reserved { + mem::drop(PositiveImbalance::::new(new_reserved - old_reserved)); + } else if new_reserved < old_reserved { + mem::drop(NegativeImbalance::::new(old_reserved - new_reserved)); + } + + Self::deposit_event(Event::BalanceSet { who, free: new_free, reserved: new_reserved }); + Ok(().into()) + } + + /// Exactly as `transfer`, except the origin must be root and the source account may be + /// specified. + /// # + /// - Same as transfer, but additional read and write because the source account is not + /// assumed to be in the overlay. + /// # + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::force_transfer())] + pub fn force_transfer( + origin: OriginFor, + source: AccountIdLookupOf, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + let source = T::Lookup::lookup(source)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer( + &source, + &dest, + value, + ExistenceRequirement::AllowDeath, + )?; + Ok(().into()) + } + + /// Same as the [`transfer`] call, but with a check that the transfer will not kill the + /// origin account. + /// + /// 99% of the time you want [`transfer`] instead. + /// + /// [`transfer`]: struct.Pallet.html#method.transfer + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::transfer_keep_alive())] + pub fn transfer_keep_alive( + origin: OriginFor, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResultWithPostInfo { + let transactor = ensure_signed(origin)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer(&transactor, &dest, value, KeepAlive)?; + Ok(().into()) + } + + /// Transfer the entire transferable balance from the caller account. + /// + /// NOTE: This function only attempts to transfer _transferable_ balances. This means that + /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be + /// transferred by this function. To ensure that this function results in a killed account, + /// you might need to prepare the account by removing any reference counters, storage + /// deposits, etc... + /// + /// The dispatch origin of this call must be Signed. + /// + /// - `dest`: The recipient of the transfer. + /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all + /// of the funds the account has, causing the sender account to be killed (false), or + /// transfer everything except at least the existential deposit, which will guarantee to + /// keep the sender account alive (true). # + /// - O(1). Just like transfer, but reading the user's transferable balance first. + /// # + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::transfer_all())] + pub fn transfer_all( + origin: OriginFor, + dest: AccountIdLookupOf, + keep_alive: bool, + ) -> DispatchResult { + use fungible::Inspect; + let transactor = ensure_signed(origin)?; + let reducible_balance = Self::reducible_balance(&transactor, keep_alive); + let dest = T::Lookup::lookup(dest)?; + let keep_alive = if keep_alive { KeepAlive } else { AllowDeath }; + >::transfer(&transactor, &dest, reducible_balance, keep_alive)?; + Ok(()) + } + + /// Unreserve some balance from a user by force. + /// + /// Can only be called by ROOT. + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::force_unreserve())] + pub fn force_unreserve( + origin: OriginFor, + who: AccountIdLookupOf, + amount: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + let _leftover = >::unreserve(&who, amount); + Ok(()) + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// An account was created with some free balance. + Endowed { account: T::AccountId, free_balance: T::Balance }, + /// An account was removed whose balance was non-zero but below ExistentialDeposit, + /// resulting in an outright loss. + DustLost { account: T::AccountId, amount: T::Balance }, + /// Transfer succeeded. + Transfer { from: T::AccountId, to: T::AccountId, amount: T::Balance }, + /// A balance was set by root. + BalanceSet { who: T::AccountId, free: T::Balance, reserved: T::Balance }, + /// Some balance was reserved (moved from free to reserved). + Reserved { who: T::AccountId, amount: T::Balance }, + /// Some balance was unreserved (moved from reserved to free). + Unreserved { who: T::AccountId, amount: T::Balance }, + /// Some balance was moved from the reserve of the first account to the second account. + /// Final argument indicates the destination balance type. + ReserveRepatriated { + from: T::AccountId, + to: T::AccountId, + amount: T::Balance, + destination_status: Status, + }, + /// Some amount was deposited (e.g. for transaction fees). + Deposit { who: T::AccountId, amount: T::Balance }, + /// Some amount was withdrawn from the account (e.g. for transaction fees). + Withdraw { who: T::AccountId, amount: T::Balance }, + /// Some amount was removed from the account (e.g. for misbehavior). + Slashed { who: T::AccountId, amount: T::Balance }, + } + + #[pallet::error] + pub enum Error { + /// Vesting balance too high to send value + VestingBalance, + /// Account liquidity restrictions prevent withdrawal + LiquidityRestrictions, + /// Balance too low to send value. + InsufficientBalance, + /// Value too low to create account due to existential deposit + ExistentialDeposit, + /// Transfer/payment would kill account + KeepAlive, + /// A vesting schedule already exists for this account + ExistingVestingSchedule, + /// Beneficiary account must pre-exist + DeadAccount, + /// Number of named reserves exceed MaxReserves + TooManyReserves, + } + + /// The total units issued in the system. + #[pallet::storage] + #[pallet::getter(fn total_issuance)] + #[pallet::whitelist_storage] + pub type TotalIssuance, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>; + + /// The total units of outstanding deactivated balance in the system. + #[pallet::storage] + #[pallet::getter(fn inactive_issuance)] + #[pallet::whitelist_storage] + pub type InactiveIssuance, I: 'static = ()> = + StorageValue<_, T::Balance, ValueQuery>; + + /// The Balances pallet example of storing the balance of an account. + /// + /// # Example + /// + /// ```nocompile + /// impl pallet_balances::Config for Runtime { + /// type AccountStore = StorageMapShim, frame_system::Provider, AccountId, Self::AccountData> + /// } + /// ``` + /// + /// You can also store the balance of an account in the `System` pallet. + /// + /// # Example + /// + /// ```nocompile + /// impl pallet_balances::Config for Runtime { + /// type AccountStore = System + /// } + /// ``` + /// + /// But this comes with tradeoffs, storing account balances in the system pallet stores + /// `frame_system` data alongside the account data contrary to storing account balances in the + /// `Balances` pallet, which uses a `StorageMap` to store balances data only. + /// NOTE: This is only used in the case that this pallet is used to store balances. + #[pallet::storage] + pub type Account, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, AccountData, ValueQuery>; + + /// Any liquidity locks on some account balances. + /// NOTE: Should only be accessed when setting, changing and freeing a lock. + #[pallet::storage] + #[pallet::getter(fn locks)] + pub type Locks, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + WeakBoundedVec, T::MaxLocks>, + ValueQuery, + >; + + /// Named reserves on some account balances. + #[pallet::storage] + #[pallet::getter(fn reserves)] + pub type Reserves, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedVec, T::MaxReserves>, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + pub balances: Vec<(T::AccountId, T::Balance)>, + } + + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { balances: Default::default() } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + let total = self.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n); + >::put(total); + + for (_, balance) in &self.balances { + assert!( + *balance >= >::ExistentialDeposit::get(), + "the balance of any account should always be at least the existential deposit.", + ) + } + + // ensure no duplicates exist. + let endowed_accounts = self + .balances + .iter() + .map(|(x, _)| x) + .cloned() + .collect::>(); + + assert!( + endowed_accounts.len() == self.balances.len(), + "duplicate balances in genesis." + ); + + for &(ref who, free) in self.balances.iter() { + assert!(T::AccountStore::insert(who, AccountData { free, ..Default::default() }) + .is_ok()); + } + } + } +} + +#[cfg(feature = "std")] +impl, I: 'static> GenesisConfig { + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + >::assimilate_storage(self, storage) + } +} + +/// Simplified reasons for withdrawing balance. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub enum Reasons { + /// Paying system transaction fees. + Fee = 0, + /// Any reason other than paying system transaction fees. + Misc = 1, + /// Any reason at all. + All = 2, +} + +impl From for Reasons { + fn from(r: WithdrawReasons) -> Reasons { + if r == WithdrawReasons::TRANSACTION_PAYMENT { + Reasons::Fee + } else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) { + Reasons::All + } else { + Reasons::Misc + } + } +} + +impl BitOr for Reasons { + type Output = Reasons; + fn bitor(self, other: Reasons) -> Reasons { + if self == other { + return self + } + Reasons::All + } +} + +/// A single lock on a balance. There can be many of these on an account and they "overlap", so the +/// same balance is frozen by multiple locks. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct BalanceLock { + /// An identifier for this lock. Only one lock may be in existence for each identifier. + pub id: LockIdentifier, + /// The amount which the free balance may not drop below when this lock is in effect. + pub amount: Balance, + /// If true, then the lock remains in effect even for payment of transaction fees. + pub reasons: Reasons, +} + +/// Store named reserved balance. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct ReserveData { + /// The identifier for the named reserve. + pub id: ReserveIdentifier, + /// The amount of the named reserve. + pub amount: Balance, +} + +/// All balance information for an account. +#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct AccountData { + /// Non-reserved part of the balance. There may still be restrictions on this, but it is the + /// total pool what may in principle be transferred, reserved and used for tipping. + /// + /// This is the only balance that matters in terms of most operations on tokens. It + /// alone is used to determine the balance when in the contract execution environment. + pub free: Balance, + /// Balance which is reserved and may not be used at all. + /// + /// This can still get slashed, but gets slashed last of all. + /// + /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens + /// that are still 'owned' by the account holder, but which are suspendable. + /// This includes named reserve and unnamed reserve. + pub reserved: Balance, + /// The amount that `free` may not drop below when withdrawing for *anything except transaction + /// fee payment*. + pub misc_frozen: Balance, + /// The amount that `free` may not drop below when withdrawing specifically for transaction + /// fee payment. + pub fee_frozen: Balance, +} + +impl AccountData { + /// How much this account's balance can be reduced for the given `reasons`. + fn usable(&self, reasons: Reasons) -> Balance { + self.free.saturating_sub(self.frozen(reasons)) + } + /// The amount that this account's free balance may not be reduced beyond for the given + /// `reasons`. + fn frozen(&self, reasons: Reasons) -> Balance { + match reasons { + Reasons::All => self.misc_frozen.max(self.fee_frozen), + Reasons::Misc => self.misc_frozen, + Reasons::Fee => self.fee_frozen, + } + } + /// The total balance in this account including any that is reserved and ignoring any frozen. + fn total(&self) -> Balance { + self.free.saturating_add(self.reserved) + } +} + +pub struct DustCleaner, I: 'static = ()>( + Option<(T::AccountId, NegativeImbalance)>, +); + +impl, I: 'static> Drop for DustCleaner { + fn drop(&mut self) { + if let Some((who, dust)) = self.0.take() { + Pallet::::deposit_event(Event::DustLost { account: who, amount: dust.peek() }); + T::DustRemoval::on_unbalanced(dust); + } + } +} + +impl, I: 'static> Pallet { + /// Get the free balance of an account. + pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).free + } + + /// Get the balance of an account that can be used for transfers, reservations, or any other + /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. + pub fn usable_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).usable(Reasons::Misc) + } + + /// Get the balance of an account that can be used for paying transaction fees (not tipping, + /// or any other kind of fees, though). Will be at most `free_balance`. + pub fn usable_balance_for_fees(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).usable(Reasons::Fee) + } + + /// Get the reserved balance of an account. + pub fn reserved_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).reserved + } + + /// Get both the free and reserved balances of an account. + fn account(who: &T::AccountId) -> AccountData { + T::AccountStore::get(who) + } + + /// Handles any steps needed after mutating an account. + /// + /// This includes DustRemoval unbalancing, in the case than the `new` account's total balance + /// is non-zero but below ED. + /// + /// Returns two values: + /// - `Some` containing the the `new` account, iff the account has sufficient balance. + /// - `Some` containing the dust to be dropped, iff some dust should be dropped. + fn post_mutation( + _who: &T::AccountId, + new: AccountData, + ) -> (Option>, Option>) { + let total = new.total(); + if total < T::ExistentialDeposit::get() { + if total.is_zero() { + (None, None) + } else { + (None, Some(NegativeImbalance::new(total))) + } + } else { + (Some(new), None) + } + } + + fn deposit_consequence( + _who: &T::AccountId, + amount: T::Balance, + account: &AccountData, + mint: bool, + ) -> DepositConsequence { + if amount.is_zero() { + return DepositConsequence::Success + } + + if mint && TotalIssuance::::get().checked_add(&amount).is_none() { + return DepositConsequence::Overflow + } + + let new_total_balance = match account.total().checked_add(&amount) { + Some(x) => x, + None => return DepositConsequence::Overflow, + }; + + if new_total_balance < T::ExistentialDeposit::get() { + return DepositConsequence::BelowMinimum + } + + // NOTE: We assume that we are a provider, so don't need to do any checks in the + // case of account creation. + + DepositConsequence::Success + } + + fn withdraw_consequence( + who: &T::AccountId, + amount: T::Balance, + account: &AccountData, + ) -> WithdrawConsequence { + if amount.is_zero() { + return WithdrawConsequence::Success + } + + if TotalIssuance::::get().checked_sub(&amount).is_none() { + return WithdrawConsequence::Underflow + } + + let new_total_balance = match account.total().checked_sub(&amount) { + Some(x) => x, + None => return WithdrawConsequence::NoFunds, + }; + + // Provider restriction - total account balance cannot be reduced to zero if it cannot + // sustain the loss of a provider reference. + // NOTE: This assumes that the pallet is a provider (which is true). Is this ever changes, + // then this will need to adapt accordingly. + let ed = T::ExistentialDeposit::get(); + let success = if new_total_balance < ed { + if frame_system::Pallet::::can_dec_provider(who) { + WithdrawConsequence::ReducedToZero(new_total_balance) + } else { + return WithdrawConsequence::WouldDie + } + } else { + WithdrawConsequence::Success + }; + + // Enough free funds to have them be reduced. + let new_free_balance = match account.free.checked_sub(&amount) { + Some(b) => b, + None => return WithdrawConsequence::NoFunds, + }; + + // Eventual free funds must be no less than the frozen balance. + let min_balance = account.frozen(Reasons::All); + if new_free_balance < min_balance { + return WithdrawConsequence::Frozen + } + + success + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + pub fn mutate_account( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData) -> R, + ) -> Result { + Self::try_mutate_account(who, |a, _| -> Result { Ok(f(a)) }) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the + /// result of `f` is an `Err`. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + fn try_mutate_account>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result { + Self::try_mutate_account_with_dust(who, f).map(|(result, dust_cleaner)| { + drop(dust_cleaner); + result + }) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the + /// result of `f` is an `Err`. + /// + /// It returns both the result from the closure, and an optional `DustCleaner` instance which + /// should be dropped once it is known that all nested mutates that could affect storage items + /// what the dust handler touches have completed. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + fn try_mutate_account_with_dust>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result<(R, DustCleaner), E> { + let result = T::AccountStore::try_mutate_exists(who, |maybe_account| { + let is_new = maybe_account.is_none(); + let mut account = maybe_account.take().unwrap_or_default(); + f(&mut account, is_new).map(move |result| { + let maybe_endowed = if is_new { Some(account.free) } else { None }; + let maybe_account_maybe_dust = Self::post_mutation(who, account); + *maybe_account = maybe_account_maybe_dust.0; + (maybe_endowed, maybe_account_maybe_dust.1, result) + }) + }); + result.map(|(maybe_endowed, maybe_dust, result)| { + if let Some(endowed) = maybe_endowed { + Self::deposit_event(Event::Endowed { account: who.clone(), free_balance: endowed }); + } + let dust_cleaner = DustCleaner(maybe_dust.map(|dust| (who.clone(), dust))); + (result, dust_cleaner) + }) + } + + /// Update the account entry for `who`, given the locks. + fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { + let bounded_locks = WeakBoundedVec::<_, T::MaxLocks>::force_from( + locks.to_vec(), + Some("Balances Update Locks"), + ); + + if locks.len() as u32 > T::MaxLocks::get() { + log::warn!( + target: LOG_TARGET, + "Warning: A user has more currency locks than expected. \ + A runtime configuration adjustment may be needed." + ); + } + // No way this can fail since we do not alter the existential balances. + let res = Self::mutate_account(who, |b| { + b.misc_frozen = Zero::zero(); + b.fee_frozen = Zero::zero(); + for l in locks.iter() { + if l.reasons == Reasons::All || l.reasons == Reasons::Misc { + b.misc_frozen = b.misc_frozen.max(l.amount); + } + if l.reasons == Reasons::All || l.reasons == Reasons::Fee { + b.fee_frozen = b.fee_frozen.max(l.amount); + } + } + }); + debug_assert!(res.is_ok()); + + let existed = Locks::::contains_key(who); + if locks.is_empty() { + Locks::::remove(who); + if existed { + // TODO: use Locks::::hashed_key + // https://github.com/paritytech/substrate/issues/4969 + system::Pallet::::dec_consumers(who); + } + } else { + Locks::::insert(who, bounded_locks); + if !existed && system::Pallet::::inc_consumers_without_limit(who).is_err() { + // No providers for the locks. This is impossible under normal circumstances + // since the funds that are under the lock will themselves be stored in the + // account and therefore will need a reference. + log::warn!( + target: LOG_TARGET, + "Warning: Attempt to introduce lock consumer reference, yet no providers. \ + This is unexpected but should be safe." + ); + } + } + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + /// + /// NOTE: returns actual amount of transferred value in `Ok` case. + fn do_transfer_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: T::Balance, + best_effort: bool, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()) + } + + if slashed == beneficiary { + return match status { + Status::Free => Ok(value.saturating_sub(Self::unreserve(slashed, value))), + Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance(slashed))), + } + } + + let ((actual, _maybe_one_dust), _maybe_other_dust) = Self::try_mutate_account_with_dust( + beneficiary, + |to_account, is_new| -> Result<(T::Balance, DustCleaner), DispatchError> { + ensure!(!is_new, Error::::DeadAccount); + Self::try_mutate_account_with_dust( + slashed, + |from_account, _| -> Result { + let actual = cmp::min(from_account.reserved, value); + ensure!(best_effort || actual == value, Error::::InsufficientBalance); + match status { + Status::Free => + to_account.free = to_account + .free + .checked_add(&actual) + .ok_or(ArithmeticError::Overflow)?, + Status::Reserved => + to_account.reserved = to_account + .reserved + .checked_add(&actual) + .ok_or(ArithmeticError::Overflow)?, + } + from_account.reserved -= actual; + Ok(actual) + }, + ) + }, + )?; + + Self::deposit_event(Event::ReserveRepatriated { + from: slashed.clone(), + to: beneficiary.clone(), + amount: actual, + destination_status: status, + }); + Ok(actual) + } +} + +impl, I: 'static> fungible::Inspect for Pallet { + type Balance = T::Balance; + + fn total_issuance() -> Self::Balance { + TotalIssuance::::get() + } + fn active_issuance() -> Self::Balance { + TotalIssuance::::get().saturating_sub(InactiveIssuance::::get()) + } + fn minimum_balance() -> Self::Balance { + T::ExistentialDeposit::get() + } + fn balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).total() + } + fn reducible_balance(who: &T::AccountId, keep_alive: bool) -> Self::Balance { + let a = Self::account(who); + // Liquid balance is what is neither reserved nor locked/frozen. + let liquid = a.free.saturating_sub(a.fee_frozen.max(a.misc_frozen)); + if frame_system::Pallet::::can_dec_provider(who) && !keep_alive { + liquid + } else { + // `must_remain_to_exist` is the part of liquid balance which must remain to keep total + // over ED. + let must_remain_to_exist = + T::ExistentialDeposit::get().saturating_sub(a.total() - liquid); + liquid.saturating_sub(must_remain_to_exist) + } + } + fn can_deposit(who: &T::AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence { + Self::deposit_consequence(who, amount, &Self::account(who), mint) + } + fn can_withdraw( + who: &T::AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + Self::withdraw_consequence(who, amount, &Self::account(who)) + } +} + +impl, I: 'static> fungible::Mutate for Pallet { + fn mint_into(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + if amount.is_zero() { + return Ok(()) + } + Self::try_mutate_account(who, |account, _is_new| -> DispatchResult { + Self::deposit_consequence(who, amount, account, true).into_result()?; + account.free += amount; + Ok(()) + })?; + TotalIssuance::::mutate(|t| *t += amount); + Self::deposit_event(Event::Deposit { who: who.clone(), amount }); + Ok(()) + } + + fn burn_from( + who: &T::AccountId, + amount: Self::Balance, + ) -> Result { + if amount.is_zero() { + return Ok(Self::Balance::zero()) + } + let actual = Self::try_mutate_account( + who, + |account, _is_new| -> Result { + let extra = Self::withdraw_consequence(who, amount, account).into_result()?; + let actual = amount + extra; + account.free -= actual; + Ok(actual) + }, + )?; + TotalIssuance::::mutate(|t| *t -= actual); + Self::deposit_event(Event::Withdraw { who: who.clone(), amount }); + Ok(actual) + } +} + +impl, I: 'static> fungible::Transfer for Pallet { + fn transfer( + source: &T::AccountId, + dest: &T::AccountId, + amount: T::Balance, + keep_alive: bool, + ) -> Result { + let er = if keep_alive { KeepAlive } else { AllowDeath }; + >::transfer(source, dest, amount, er).map(|_| amount) + } + + fn deactivate(amount: Self::Balance) { + InactiveIssuance::::mutate(|b| b.saturating_accrue(amount)); + } + + fn reactivate(amount: Self::Balance) { + InactiveIssuance::::mutate(|b| b.saturating_reduce(amount)); + } +} + +impl, I: 'static> fungible::Unbalanced for Pallet { + fn set_balance(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + Self::mutate_account(who, |account| -> DispatchResult { + // fungibles::Unbalanced::decrease_balance didn't check account.reserved + // free = new_balance - reserved + account.free = + amount.checked_sub(&account.reserved).ok_or(ArithmeticError::Underflow)?; + Self::deposit_event(Event::BalanceSet { + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + + Ok(()) + })? + } + + fn set_total_issuance(amount: Self::Balance) { + TotalIssuance::::mutate(|t| *t = amount); + } +} + +impl, I: 'static> fungible::InspectHold for Pallet { + fn balance_on_hold(who: &T::AccountId) -> T::Balance { + Self::account(who).reserved + } + fn can_hold(who: &T::AccountId, amount: T::Balance) -> bool { + let a = Self::account(who); + let min_balance = T::ExistentialDeposit::get().max(a.frozen(Reasons::All)); + if a.reserved.checked_add(&amount).is_none() { + return false + } + // We require it to be min_balance + amount to ensure that the full reserved funds may be + // slashed without compromising locked funds or destroying the account. + let required_free = match min_balance.checked_add(&amount) { + Some(x) => x, + None => return false, + }; + a.free >= required_free + } +} +impl, I: 'static> fungible::MutateHold for Pallet { + fn hold(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + if amount.is_zero() { + return Ok(()) + } + ensure!(Self::can_reserve(who, amount), Error::::InsufficientBalance); + Self::mutate_account(who, |a| { + a.free -= amount; + a.reserved += amount; + })?; + Ok(()) + } + fn release( + who: &T::AccountId, + amount: Self::Balance, + best_effort: bool, + ) -> Result { + if amount.is_zero() { + return Ok(amount) + } + // Done on a best-effort basis. + Self::try_mutate_account(who, |a, _| { + let new_free = a.free.saturating_add(amount.min(a.reserved)); + let actual = new_free - a.free; + ensure!(best_effort || actual == amount, Error::::InsufficientBalance); + // ^^^ Guaranteed to be <= amount and <= a.reserved + a.free = new_free; + a.reserved = a.reserved.saturating_sub(actual); + Ok(actual) + }) + } + fn transfer_held( + source: &T::AccountId, + dest: &T::AccountId, + amount: Self::Balance, + best_effort: bool, + on_hold: bool, + ) -> Result { + let status = if on_hold { Status::Reserved } else { Status::Free }; + Self::do_transfer_reserved(source, dest, amount, best_effort, status) + } +} + +// wrapping these imbalances in a private module is necessary to ensure absolute privacy +// of the inner member. +mod imbalances { + use super::{result, Config, Imbalance, RuntimeDebug, Saturating, TryDrop, Zero}; + use frame_support::traits::SameOrOther; + use sp_std::mem; + + /// Opaque, move-only struct with private fields that serves as a token denoting that + /// funds have been created without any equal and opposite accounting. + #[must_use] + #[derive(RuntimeDebug, PartialEq, Eq)] + pub struct PositiveImbalance, I: 'static = ()>(T::Balance); + + impl, I: 'static> PositiveImbalance { + /// Create a new positive imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + PositiveImbalance(amount) + } + } + + /// Opaque, move-only struct with private fields that serves as a token denoting that + /// funds have been destroyed without any equal and opposite accounting. + #[must_use] + #[derive(RuntimeDebug, PartialEq, Eq)] + pub struct NegativeImbalance, I: 'static = ()>(T::Balance); + + impl, I: 'static> NegativeImbalance { + /// Create a new negative imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + NegativeImbalance(amount) + } + } + + impl, I: 'static> TryDrop for PositiveImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } + } + + impl, I: 'static> Default for PositiveImbalance { + fn default() -> Self { + Self::zero() + } + } + + impl, I: 'static> Imbalance for PositiveImbalance { + type Opposite = NegativeImbalance; + + fn zero() -> Self { + Self(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0 - first; + + mem::forget(self); + (Self(first), Self(second)) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self(a - b)) + } else if b > a { + SameOrOther::Other(NegativeImbalance::new(b - a)) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + } + + impl, I: 'static> TryDrop for NegativeImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } + } + + impl, I: 'static> Default for NegativeImbalance { + fn default() -> Self { + Self::zero() + } + } + + impl, I: 'static> Imbalance for NegativeImbalance { + type Opposite = PositiveImbalance; + + fn zero() -> Self { + Self(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0 - first; + + mem::forget(self); + (Self(first), Self(second)) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self(a - b)) + } else if b > a { + SameOrOther::Other(PositiveImbalance::new(b - a)) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + } + + impl, I: 'static> Drop for PositiveImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + >::mutate(|v| *v = v.saturating_add(self.0)); + } + } + + impl, I: 'static> Drop for NegativeImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + >::mutate(|v| *v = v.saturating_sub(self.0)); + } + } +} + +impl, I: 'static> Currency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + type Balance = T::Balance; + type PositiveImbalance = PositiveImbalance; + type NegativeImbalance = NegativeImbalance; + + fn total_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).total() + } + + // Check if `value` amount of free balance can be slashed from `who`. + fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true + } + Self::free_balance(who) >= value + } + + fn total_issuance() -> Self::Balance { + TotalIssuance::::get() + } + + fn active_issuance() -> Self::Balance { + >::active_issuance() + } + + fn deactivate(amount: Self::Balance) { + >::deactivate(amount); + } + + fn reactivate(amount: Self::Balance) { + >::reactivate(amount); + } + + fn minimum_balance() -> Self::Balance { + T::ExistentialDeposit::get() + } + + // Burn funds from the total issuance, returning a positive imbalance for the amount burned. + // Is a no-op if amount to be burned is zero. + fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { + if amount.is_zero() { + return PositiveImbalance::zero() + } + >::mutate(|issued| { + *issued = issued.checked_sub(&amount).unwrap_or_else(|| { + amount = *issued; + Zero::zero() + }); + }); + PositiveImbalance::new(amount) + } + + // Create new funds into the total issuance, returning a negative imbalance + // for the amount issued. + // Is a no-op if amount to be issued it zero. + fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { + if amount.is_zero() { + return NegativeImbalance::zero() + } + >::mutate(|issued| { + *issued = issued.checked_add(&amount).unwrap_or_else(|| { + amount = Self::Balance::max_value() - *issued; + Self::Balance::max_value() + }) + }); + NegativeImbalance::new(amount) + } + + fn free_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).free + } + + // Ensure that an account can withdraw from their free balance given any existing withdrawal + // restrictions like locks and vesting balance. + // Is a no-op if amount to be withdrawn is zero. + // + // # + // Despite iterating over a list of locks, they are limited by the number of + // lock IDs, which means the number of runtime pallets that intend to use and create locks. + // # + fn ensure_can_withdraw( + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + new_balance: T::Balance, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()) + } + let min_balance = Self::account(who).frozen(reasons.into()); + ensure!(new_balance >= min_balance, Error::::LiquidityRestrictions); + Ok(()) + } + + // Transfer some free balance from `transactor` to `dest`, respecting existence requirements. + // Is a no-op if value to be transferred is zero or the `transactor` is the same as `dest`. + fn transfer( + transactor: &T::AccountId, + dest: &T::AccountId, + value: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + if value.is_zero() || transactor == dest { + return Ok(()) + } + + Self::try_mutate_account_with_dust( + dest, + |to_account, _| -> Result, DispatchError> { + Self::try_mutate_account_with_dust( + transactor, + |from_account, _| -> DispatchResult { + from_account.free = from_account + .free + .checked_sub(&value) + .ok_or(Error::::InsufficientBalance)?; + + // NOTE: total stake being stored in the same type means that this could + // never overflow but better to be safe than sorry. + to_account.free = + to_account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?; + + let ed = T::ExistentialDeposit::get(); + ensure!(to_account.total() >= ed, Error::::ExistentialDeposit); + + Self::ensure_can_withdraw( + transactor, + value, + WithdrawReasons::TRANSFER, + from_account.free, + ) + .map_err(|_| Error::::LiquidityRestrictions)?; + + // TODO: This is over-conservative. There may now be other providers, and + // this pallet may not even be a provider. + let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; + let allow_death = + allow_death && system::Pallet::::can_dec_provider(transactor); + ensure!( + allow_death || from_account.total() >= ed, + Error::::KeepAlive + ); + + Ok(()) + }, + ) + .map(|(_, maybe_dust_cleaner)| maybe_dust_cleaner) + }, + )?; + + // Emit transfer event. + Self::deposit_event(Event::Transfer { + from: transactor.clone(), + to: dest.clone(), + amount: value, + }); + + Ok(()) + } + + /// Slash a target account `who`, returning the negative imbalance created and any left over + /// amount that could not be slashed. + /// + /// Is a no-op if `value` to be slashed is zero or the account does not exist. + /// + /// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn + /// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid + /// having to draw from reserved funds, however we err on the side of punishment if things are + /// inconsistent or `can_slash` wasn't used appropriately. + fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()) + } + if Self::total_balance(who).is_zero() { + return (NegativeImbalance::zero(), value) + } + + for attempt in 0..2 { + match Self::try_mutate_account( + who, + |account, + _is_new| + -> Result<(Self::NegativeImbalance, Self::Balance), DispatchError> { + // Best value is the most amount we can slash following liveness rules. + let best_value = match attempt { + // First attempt we try to slash the full amount, and see if liveness issues + // happen. + 0 => value, + // If acting as a critical provider (i.e. first attempt failed), then slash + // as much as possible while leaving at least at ED. + _ => value.min( + (account.free + account.reserved) + .saturating_sub(T::ExistentialDeposit::get()), + ), + }; + + let free_slash = cmp::min(account.free, best_value); + account.free -= free_slash; // Safe because of above check + let remaining_slash = best_value - free_slash; // Safe because of above check + + if !remaining_slash.is_zero() { + // If we have remaining slash, take it from reserved balance. + let reserved_slash = cmp::min(account.reserved, remaining_slash); + account.reserved -= reserved_slash; // Safe because of above check + Ok(( + NegativeImbalance::new(free_slash + reserved_slash), + value - free_slash - reserved_slash, /* Safe because value is gt or + * eq total slashed */ + )) + } else { + // Else we are done! + Ok(( + NegativeImbalance::new(free_slash), + value - free_slash, // Safe because value is gt or eq to total slashed + )) + } + }, + ) { + Ok((imbalance, not_slashed)) => { + Self::deposit_event(Event::Slashed { + who: who.clone(), + amount: value.saturating_sub(not_slashed), + }); + return (imbalance, not_slashed) + }, + Err(_) => (), + } + } + + // Should never get here. But we'll be defensive anyway. + (Self::NegativeImbalance::zero(), value) + } + + /// Deposit some `value` into the free balance of an existing target account `who`. + /// + /// Is a no-op if the `value` to be deposited is zero. + fn deposit_into_existing( + who: &T::AccountId, + value: Self::Balance, + ) -> Result { + if value.is_zero() { + return Ok(PositiveImbalance::zero()) + } + + Self::try_mutate_account( + who, + |account, is_new| -> Result { + ensure!(!is_new, Error::::DeadAccount); + account.free = account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?; + Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); + Ok(PositiveImbalance::new(value)) + }, + ) + } + + /// Deposit some `value` into the free balance of `who`, possibly creating a new account. + /// + /// This function is a no-op if: + /// - the `value` to be deposited is zero; or + /// - the `value` to be deposited is less than the required ED and the account does not yet + /// exist; or + /// - the deposit would necessitate the account to exist and there are no provider references; + /// or + /// - `value` is so large it would cause the balance of `who` to overflow. + fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { + if value.is_zero() { + return Self::PositiveImbalance::zero() + } + + Self::try_mutate_account( + who, + |account, is_new| -> Result { + let ed = T::ExistentialDeposit::get(); + ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); + + // defensive only: overflow should never happen, however in case it does, then this + // operation is a no-op. + account.free = match account.free.checked_add(&value) { + Some(x) => x, + None => return Ok(Self::PositiveImbalance::zero()), + }; + + Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); + Ok(PositiveImbalance::new(value)) + }, + ) + .unwrap_or_else(|_| Self::PositiveImbalance::zero()) + } + + /// Withdraw some free balance from an account, respecting existence requirements. + /// + /// Is a no-op if value to be withdrawn is zero. + fn withdraw( + who: &T::AccountId, + value: Self::Balance, + reasons: WithdrawReasons, + liveness: ExistenceRequirement, + ) -> result::Result { + if value.is_zero() { + return Ok(NegativeImbalance::zero()) + } + + Self::try_mutate_account( + who, + |account, _| -> Result { + let new_free_account = + account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; + + // bail if we need to keep the account alive and this would kill it. + let ed = T::ExistentialDeposit::get(); + let would_be_dead = new_free_account + account.reserved < ed; + let would_kill = would_be_dead && account.free + account.reserved >= ed; + ensure!(liveness == AllowDeath || !would_kill, Error::::KeepAlive); + + Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; + + account.free = new_free_account; + + Self::deposit_event(Event::Withdraw { who: who.clone(), amount: value }); + Ok(NegativeImbalance::new(value)) + }, + ) + } + + /// Force the new free balance of a target account `who` to some new value `balance`. + fn make_free_balance_be( + who: &T::AccountId, + value: Self::Balance, + ) -> SignedImbalance { + Self::try_mutate_account( + who, + |account, + is_new| + -> Result, DispatchError> { + let ed = T::ExistentialDeposit::get(); + let total = value.saturating_add(account.reserved); + // If we're attempting to set an existing account to less than ED, then + // bypass the entire operation. It's a no-op if you follow it through, but + // since this is an instance where we might account for a negative imbalance + // (in the dust cleaner of set_account) before we account for its actual + // equal and opposite cause (returned as an Imbalance), then in the + // instance that there's no other accounts on the system at all, we might + // underflow the issuance and our arithmetic will be off. + ensure!(total >= ed || !is_new, Error::::ExistentialDeposit); + + let imbalance = if account.free <= value { + SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) + } else { + SignedImbalance::Negative(NegativeImbalance::new(account.free - value)) + }; + account.free = value; + Self::deposit_event(Event::BalanceSet { + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + Ok(imbalance) + }, + ) + .unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) + } +} + +impl, I: 'static> ReservableCurrency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + /// Check if `who` can reserve `value` from their free balance. + /// + /// Always `true` if value to be reserved is zero. + fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true + } + Self::account(who).free.checked_sub(&value).map_or(false, |new_balance| { + Self::ensure_can_withdraw(who, value, WithdrawReasons::RESERVE, new_balance).is_ok() + }) + } + + fn reserved_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).reserved + } + + /// Move `value` from the free balance from `who` to their reserved balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { + if value.is_zero() { + return Ok(()) + } + + Self::try_mutate_account(who, |account, _| -> DispatchResult { + account.free = + account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; + account.reserved = + account.reserved.checked_add(&value).ok_or(ArithmeticError::Overflow)?; + Self::ensure_can_withdraw(&who, value, WithdrawReasons::RESERVE, account.free) + })?; + + Self::deposit_event(Event::Reserved { who: who.clone(), amount: value }); + Ok(()) + } + + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero or the account does not exist. + /// + /// NOTE: returns amount value which wasn't successfully unreserved. + fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { + if value.is_zero() { + return Zero::zero() + } + if Self::total_balance(who).is_zero() { + return value + } + + let actual = match Self::mutate_account(who, |account| { + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + // defensive only: this can never fail since total issuance which is at least + // free+reserved fits into the same data type. + account.free = account.free.defensive_saturating_add(actual); + actual + }) { + Ok(x) => x, + Err(_) => { + // This should never happen since we don't alter the total amount in the account. + // If it ever does, then we should fail gracefully though, indicating that nothing + // could be done. + return value + }, + }; + + Self::deposit_event(Event::Unreserved { who: who.clone(), amount: actual }); + value - actual + } + + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero or the account does not exist. + fn slash_reserved( + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()) + } + if Self::total_balance(who).is_zero() { + return (NegativeImbalance::zero(), value) + } + + // NOTE: `mutate_account` may fail if it attempts to reduce the balance to the point that an + // account is attempted to be illegally destroyed. + + for attempt in 0..2 { + match Self::mutate_account(who, |account| { + let best_value = match attempt { + 0 => value, + // If acting as a critical provider (i.e. first attempt failed), then ensure + // slash leaves at least the ED. + _ => value.min( + (account.free + account.reserved) + .saturating_sub(T::ExistentialDeposit::get()), + ), + }; + + let actual = cmp::min(account.reserved, best_value); + account.reserved -= actual; + + // underflow should never happen, but it if does, there's nothing to be done here. + (NegativeImbalance::new(actual), value - actual) + }) { + Ok((imbalance, not_slashed)) => { + Self::deposit_event(Event::Slashed { + who: who.clone(), + amount: value.saturating_sub(not_slashed), + }); + return (imbalance, not_slashed) + }, + Err(_) => (), + } + } + // Should never get here as we ensure that ED is left in the second attempt. + // In case we do, though, then we fail gracefully. + (Self::NegativeImbalance::zero(), value) + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + fn repatriate_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + let actual = Self::do_transfer_reserved(slashed, beneficiary, value, true, status)?; + Ok(value.saturating_sub(actual)) + } +} + +impl, I: 'static> NamedReservableCurrency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + type ReserveIdentifier = T::ReserveIdentifier; + + fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { + let reserves = Self::reserves(who); + reserves + .binary_search_by_key(id, |data| data.id) + .map(|index| reserves[index].amount) + .unwrap_or_default() + } + + /// Move `value` from the free balance from `who` to a named reserve balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> DispatchResult { + if value.is_zero() { + return Ok(()) + } + + Reserves::::try_mutate(who, |reserves| -> DispatchResult { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + // this add can't overflow but just to be defensive. + reserves[index].amount = reserves[index].amount.defensive_saturating_add(value); + }, + Err(index) => { + reserves + .try_insert(index, ReserveData { id: *id, amount: value }) + .map_err(|_| Error::::TooManyReserves)?; + }, + }; + >::reserve(who, value)?; + Ok(()) + }) + } + + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero. + fn unreserve_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> Self::Balance { + if value.is_zero() { + return Zero::zero() + } + + Reserves::::mutate_exists(who, |maybe_reserves| -> Self::Balance { + if let Some(reserves) = maybe_reserves.as_mut() { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let remain = >::unreserve(who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + if reserves[index].amount.is_zero() { + if reserves.len() == 1 { + // no more named reserves + *maybe_reserves = None; + } else { + // remove this named reserve + reserves.remove(index); + } + } + + value - actual + }, + Err(_) => value, + } + } else { + value + } + }) + } + + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero. + fn slash_reserved_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()) + } + + Reserves::::mutate(who, |reserves| -> (Self::NegativeImbalance, Self::Balance) { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let (imb, remain) = + >::slash_reserved(who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + Self::deposit_event(Event::Slashed { who: who.clone(), amount: actual }); + (imb, value - actual) + }, + Err(_) => (NegativeImbalance::zero(), value), + } + }) + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// If `status` is `Reserved`, the balance will be reserved with given `id`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + fn repatriate_reserved_named( + id: &Self::ReserveIdentifier, + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()) + } + + if slashed == beneficiary { + return match status { + Status::Free => Ok(Self::unreserve_named(id, slashed, value)), + Status::Reserved => + Ok(value.saturating_sub(Self::reserved_balance_named(id, slashed))), + } + } + + Reserves::::try_mutate(slashed, |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let actual = if status == Status::Reserved { + // make it the reserved under same identifier + Reserves::::try_mutate( + beneficiary, + |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let remain = + >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive + // here. + let actual = to_change.defensive_saturating_sub(remain); + + // this add can't overflow but just to be defensive. + reserves[index].amount = + reserves[index].amount.defensive_saturating_add(actual); + + Ok(actual) + }, + Err(index) => { + let remain = + >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive + // here + let actual = to_change.defensive_saturating_sub(remain); + + reserves + .try_insert( + index, + ReserveData { id: *id, amount: actual }, + ) + .map_err(|_| Error::::TooManyReserves)?; + + Ok(actual) + }, + } + }, + )? + } else { + let remain = >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive here + to_change.defensive_saturating_sub(remain) + }; + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + Ok(value - actual) + }, + Err(_) => Ok(value), + } + }) + } +} + +impl, I: 'static> LockableCurrency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + type Moment = T::BlockNumber; + + type MaxLocks = T::MaxLocks; + + // Set a lock on the balance of `who`. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. + fn set_lock( + id: LockIdentifier, + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + ) { + if amount.is_zero() || reasons.is_empty() { + return + } + let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); + let mut locks = Self::locks(who) + .into_iter() + .filter_map(|l| if l.id == id { new_lock.take() } else { Some(l) }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(who, &locks[..]); + } + + // Extend a lock on the balance of `who`. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. + fn extend_lock( + id: LockIdentifier, + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + ) { + if amount.is_zero() || reasons.is_empty() { + return + } + let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); + let mut locks = Self::locks(who) + .into_iter() + .filter_map(|l| { + if l.id == id { + new_lock.take().map(|nl| BalanceLock { + id: l.id, + amount: l.amount.max(nl.amount), + reasons: l.reasons | nl.reasons, + }) + } else { + Some(l) + } + }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(who, &locks[..]); + } + + fn remove_lock(id: LockIdentifier, who: &T::AccountId) { + let mut locks = Self::locks(who); + locks.retain(|l| l.id != id); + Self::update_locks(who, &locks[..]); + } +} diff --git a/pallets/balances/src/migration.rs b/pallets/balances/src/migration.rs new file mode 100644 index 000000000..6d47a16f4 --- /dev/null +++ b/pallets/balances/src/migration.rs @@ -0,0 +1,103 @@ +// // Copyright 2017-2020 Parity Technologies (UK) Ltd. +// // This file is part of Polkadot. + +// // Polkadot is free software: you can redistribute it and/or modify +// // it under the terms of the GNU General Public License as published by +// // the Free Software Foundation, either version 3 of the License, or +// // (at your option) any later version. + +// // Polkadot is distributed in the hope that it will be useful, +// // but WITHOUT ANY WARRANTY; without even the implied warranty of +// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// // GNU General Public License for more details. + +// // You should have received a copy of the GNU General Public License +// // along with Polkadot. If not, see . + +// use super::*; +// use frame_support::{ +// pallet_prelude::*, +// traits::{OnRuntimeUpgrade, PalletInfoAccess}, +// weights::Weight, +// }; + +// fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { +// let onchain_version = Pallet::::on_chain_storage_version(); + +// if onchain_version == 0 { +// let total = accounts +// .iter() +// .map(|a| Pallet::::total_balance(a)) +// .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); +// Pallet::::deactivate(total); + +// // Remove the old `StorageVersion` type. +// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( +// Pallet::::name().as_bytes(), +// "StorageVersion".as_bytes(), +// )); + +// // Set storage version to `1`. +// StorageVersion::new(1).put::>(); + +// log::info!(target: LOG_TARGET, "Storage to version 1"); +// T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) +// } else { +// log::info!( +// target: LOG_TARGET, +// "Migration did not execute. This probably should be removed" +// ); +// T::DbWeight::get().reads(1) +// } +// } + +// // NOTE: This must be used alongside the account whose balance is expected to be inactive. +// // Generally this will be used for the XCM teleport checking account. +// pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); +// impl, A: Get, I: 'static> OnRuntimeUpgrade +// for MigrateToTrackInactive +// { +// fn on_runtime_upgrade() -> Weight { +// migrate_v0_to_v1::(&[A::get()]) +// } +// } + +// // NOTE: This must be used alongside the accounts whose balance is expected to be inactive. +// // Generally this will be used for the XCM teleport checking accounts. +// pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); +// impl, A: Get>, I: 'static> OnRuntimeUpgrade +// for MigrateManyToTrackInactive +// { +// fn on_runtime_upgrade() -> Weight { +// migrate_v0_to_v1::(&A::get()) +// } +// } + +// pub struct ResetInactive(PhantomData<(T, I)>); +// impl, I: 'static> OnRuntimeUpgrade for ResetInactive { +// fn on_runtime_upgrade() -> Weight { +// let onchain_version = Pallet::::on_chain_storage_version(); + +// if onchain_version == 1 { +// // Remove the old `StorageVersion` type. +// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( +// Pallet::::name().as_bytes(), +// "StorageVersion".as_bytes(), +// )); + +// InactiveIssuance::::kill(); + +// // Set storage version to `0`. +// StorageVersion::new(0).put::>(); + +// log::info!(target: LOG_TARGET, "Storage to version 0"); +// T::DbWeight::get().reads_writes(1, 2) +// } else { +// log::info!( +// target: LOG_TARGET, +// "Migration did not execute. This probably should be removed" +// ); +// T::DbWeight::get().reads(1) +// } +// } +// } diff --git a/pallets/balances/src/tests.rs b/pallets/balances/src/tests.rs new file mode 100644 index 000000000..2869b547d --- /dev/null +++ b/pallets/balances/src/tests.rs @@ -0,0 +1,1456 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2017-2022 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. + +// //! Macro for creating the tests for the module. + +// #![cfg(test)] + +// #[macro_export] +// macro_rules! decl_tests { +// ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { + +// use crate::*; +// use sp_runtime::{ArithmeticError, TokenError, FixedPointNumber, traits::{SignedExtension, BadOrigin}}; +// use frame_support::{ +// assert_noop, assert_storage_noop, assert_ok, assert_err, +// traits::{ +// LockableCurrency, LockIdentifier, WithdrawReasons, +// Currency, ReservableCurrency, ExistenceRequirement::AllowDeath +// } +// }; +// use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; +// use frame_system::RawOrigin; + +// const ID_1: LockIdentifier = *b"1 "; +// const ID_2: LockIdentifier = *b"2 "; + +// pub const CALL: &<$test as frame_system::Config>::RuntimeCall = +// &RuntimeCall::Balances(pallet_balances::Call::transfer { dest: 0, value: 0 }); + +// /// create a transaction info struct from weight. Handy to avoid building the whole struct. +// pub fn info_from_weight(w: Weight) -> DispatchInfo { +// DispatchInfo { weight: w, ..Default::default() } +// } + +// fn events() -> Vec { +// let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + +// System::reset_events(); + +// evt +// } + +// #[test] +// fn basic_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// assert_eq!(Balances::free_balance(1), 10); +// Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 5, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn account_should_be_reaped() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// assert_eq!(Balances::free_balance(1), 10); +// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); +// // Check that the account is dead. +// assert!(!frame_system::Account::::contains_key(&1)); +// }); +// } + +// #[test] +// fn reap_failed_due_to_provider_and_consumer() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// // SCENARIO: only one provider and there are remaining consumers. +// assert_ok!(System::inc_consumers(&1)); +// assert!(!System::can_dec_provider(&1)); +// assert_noop!( +// >::transfer(&1, &2, 10, AllowDeath), +// Error::<$test, _>::KeepAlive +// ); +// assert!(System::account_exists(&1)); +// assert_eq!(Balances::free_balance(1), 10); + +// // SCENARIO: more than one provider, but will not kill account due to other provider. +// assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); +// assert_eq!(System::providers(&1), 2); +// assert!(System::can_dec_provider(&1)); +// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); +// assert_eq!(System::providers(&1), 1); +// assert!(System::account_exists(&1)); +// assert_eq!(Balances::free_balance(1), 0); +// }); +// } + +// #[test] +// fn partial_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn lock_removal_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); +// Balances::remove_lock(ID_1, &1); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn lock_replacement_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn double_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn combination_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); +// Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn lock_value_extension_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 3, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn lock_reasons_should_work() { +// <$ext_builder>::default() +// .existential_deposit(1) +// .monied(true) +// .build() +// .execute_with(|| { +// pallet_transaction_payment::NextFeeMultiplier::<$test>::put( +// Multiplier::saturating_from_integer(1) +// ); +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); +// assert_noop!( +// >::transfer(&1, &2, 1, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// assert_noop!( +// >::reserve(&1, 1), +// Error::<$test, _>::LiquidityRestrictions, +// ); +// assert!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(1), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// ).is_err()); +// assert_ok!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(0), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// )); + +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// assert_ok!(>::reserve(&1, 1)); +// assert!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(1), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// ).is_err()); +// assert!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(0), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// ).is_err()); +// }); +// } + +// #[test] +// fn lock_block_number_extension_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// System::set_block_number(2); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 3, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn lock_reasons_extension_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn default_indexing_on_new_accounts_should_not_work2() { +// <$ext_builder>::default() +// .existential_deposit(10) +// .monied(true) +// .build() +// .execute_with(|| { +// // account 5 should not exist +// // ext_deposit is 10, value is 9, not satisfies for ext_deposit +// assert_noop!( +// Balances::transfer(Some(1).into(), 5, 9), +// Error::<$test, _>::ExistentialDeposit, +// ); +// assert_eq!(Balances::free_balance(1), 100); +// }); +// } + +// #[test] +// fn reserved_balance_should_prevent_reclaim_count() { +// <$ext_builder>::default() +// .existential_deposit(256 * 1) +// .monied(true) +// .build() +// .execute_with(|| { +// System::inc_account_nonce(&2); +// assert_eq!(Balances::total_balance(&2), 256 * 20); + +// assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved +// assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." +// assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. +// assert_eq!(System::account_nonce(&2), 1); + +// // account 4 tries to take index 1 for account 5. +// assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); +// assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); + +// assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed +// // "reserve" account reduced to 255 (below ED) so account deleted +// assert_eq!(Balances::total_balance(&2), 0); +// assert_eq!(System::account_nonce(&2), 0); // nonce zero + +// // account 4 tries to take index 1 again for account 6. +// assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); +// assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); +// }); +// } + +// #[test] +// fn reward_should_work() { +// <$ext_builder>::default().monied(true).build().execute_with(|| { +// assert_eq!(Balances::total_balance(&1), 10); +// assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 })); +// assert_eq!(Balances::total_balance(&1), 20); +// assert_eq!(>::get(), 120); +// }); +// } + +// #[test] +// fn dust_account_removal_should_work() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .monied(true) +// .build() +// .execute_with(|| { +// System::inc_account_nonce(&2); +// assert_eq!(System::account_nonce(&2), 1); +// assert_eq!(Balances::total_balance(&2), 2000); +// // index 1 (account 2) becomes zombie +// assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); +// assert_eq!(Balances::total_balance(&2), 0); +// assert_eq!(Balances::total_balance(&5), 1901); +// assert_eq!(System::account_nonce(&2), 0); +// }); +// } + +// #[test] +// fn balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 42); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 42 })); +// assert_eq!(Balances::free_balance(1), 42); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(Balances::total_balance(&1), 42); +// assert_eq!(Balances::free_balance(2), 0); +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::total_balance(&2), 0); +// }); +// } + +// #[test] +// fn balance_transfer_works() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); +// assert_eq!(Balances::total_balance(&1), 42); +// assert_eq!(Balances::total_balance(&2), 69); +// }); +// } + +// #[test] +// fn force_transfer_works() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_noop!( +// Balances::force_transfer(Some(2).into(), 1, 2, 69), +// BadOrigin, +// ); +// assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); +// assert_eq!(Balances::total_balance(&1), 42); +// assert_eq!(Balances::total_balance(&2), 69); +// }); +// } + +// #[test] +// fn reserving_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 111); +// assert_eq!(Balances::reserved_balance(1), 0); + +// assert_ok!(Balances::reserve(&1, 69)); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 42); +// assert_eq!(Balances::reserved_balance(1), 69); +// }); +// } + +// #[test] +// fn balance_transfer_when_reserved_should_not_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 69)); +// assert_noop!( +// Balances::transfer(Some(1).into(), 2, 69), +// Error::<$test, _>::InsufficientBalance, +// ); +// }); +// } + +// #[test] +// fn deducting_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 69)); +// assert_eq!(Balances::free_balance(1), 42); +// }); +// } + +// #[test] +// fn refunding_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 42); +// assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); +// Balances::unreserve(&1, 69); +// assert_eq!(Balances::free_balance(1), 111); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn slashing_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 69)); +// assert!(Balances::slash(&1, 69).1.is_zero()); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 42); +// assert_eq!(>::get(), 42); +// }); +// } + +// #[test] +// fn withdrawing_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&2, 111); +// let _ = Balances::withdraw( +// &2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive +// ); +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Withdraw { who: 2, amount: 11 })); +// assert_eq!(Balances::free_balance(2), 100); +// assert_eq!(>::get(), 100); +// }); +// } + +// #[test] +// fn slashing_incomplete_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 42); +// assert_ok!(Balances::reserve(&1, 21)); +// assert_eq!(Balances::slash(&1, 69).1, 27); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(>::get(), 0); +// }); +// } + +// #[test] +// fn unreserving_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 111)); +// Balances::unreserve(&1, 42); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 42); +// }); +// } + +// #[test] +// fn slashing_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 111)); +// assert_eq!(Balances::slash_reserved(&1, 42).1, 0); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(>::get(), 69); +// }); +// } + +// #[test] +// fn slashing_incomplete_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 42)); +// assert_eq!(Balances::slash_reserved(&1, 69).1, 27); +// assert_eq!(Balances::free_balance(1), 69); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(>::get(), 69); +// }); +// } + +// #[test] +// fn repatriating_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 1); +// assert_ok!(Balances::reserve(&1, 110)); +// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); +// System::assert_last_event( +// RuntimeEvent::Balances(crate::Event::ReserveRepatriated { from: 1, to: 2, amount: 41, destination_status: Status::Free }) +// ); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::free_balance(2), 42); +// }); +// } + +// #[test] +// fn transferring_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 1); +// assert_ok!(Balances::reserve(&1, 110)); +// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(2), 41); +// assert_eq!(Balances::free_balance(2), 1); +// }); +// } + +// #[test] +// fn transferring_reserved_balance_to_yourself_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// assert_ok!(Balances::reserve(&1, 50)); +// assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Status::Free), 0); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance(1), 0); + +// assert_ok!(Balances::reserve(&1, 50)); +// assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Status::Free), 10); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn transferring_reserved_balance_to_nonexistent_should_fail() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 111)); +// assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); +// }); +// } + +// #[test] +// fn transferring_incomplete_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 1); +// assert_ok!(Balances::reserve(&1, 41)); +// assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Status::Free), 28); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(Balances::free_balance(1), 69); +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::free_balance(2), 42); +// }); +// } + +// #[test] +// fn transferring_too_high_value_should_not_panic() { +// <$ext_builder>::default().build().execute_with(|| { +// Balances::make_free_balance_be(&1, u64::MAX); +// Balances::make_free_balance_be(&2, 1); + +// assert_err!( +// Balances::transfer(Some(1).into(), 2, u64::MAX), +// ArithmeticError::Overflow, +// ); + +// assert_eq!(Balances::free_balance(1), u64::MAX); +// assert_eq!(Balances::free_balance(2), 1); +// }); +// } + +// #[test] +// fn account_create_on_free_too_low_with_other() { +// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 100); +// assert_eq!(>::get(), 100); + +// // No-op. +// let _ = Balances::deposit_creating(&2, 50); +// assert_eq!(Balances::free_balance(2), 0); +// assert_eq!(>::get(), 100); +// }) +// } + +// #[test] +// fn account_create_on_free_too_low() { +// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { +// // No-op. +// let _ = Balances::deposit_creating(&2, 50); +// assert_eq!(Balances::free_balance(2), 0); +// assert_eq!(>::get(), 0); +// }) +// } + +// #[test] +// fn account_removal_on_free_too_low() { +// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { +// assert_eq!(>::get(), 0); + +// // Setup two accounts with free balance above the existential threshold. +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 110); + +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::free_balance(2), 110); +// assert_eq!(>::get(), 220); + +// // Transfer funds from account 1 of such amount that after this transfer +// // the balance of account 1 will be below the existential threshold. +// // This should lead to the removal of all balance of this account. +// assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); + +// // Verify free balance removal of account 1. +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::free_balance(2), 130); + +// // Verify that TotalIssuance tracks balance removal when free balance is too low. +// assert_eq!(>::get(), 130); +// }); +// } + +// #[test] +// fn burn_must_work() { +// <$ext_builder>::default().monied(true).build().execute_with(|| { +// let init_total_issuance = Balances::total_issuance(); +// let imbalance = Balances::burn(10); +// assert_eq!(Balances::total_issuance(), init_total_issuance - 10); +// drop(imbalance); +// assert_eq!(Balances::total_issuance(), init_total_issuance); +// }); +// } + +// #[test] +// fn transfer_keep_alive_works() { +// <$ext_builder>::default().existential_deposit(1).build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 100); +// assert_noop!( +// Balances::transfer_keep_alive(Some(1).into(), 2, 100), +// Error::<$test, _>::KeepAlive +// ); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 0); +// }); +// } + +// #[test] +// #[should_panic = "the balance of any account should always be at least the existential deposit."] +// fn cannot_set_genesis_value_below_ed() { +// ($existential_deposit).with(|v| *v.borrow_mut() = 11); +// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); +// let _ = pallet_balances::GenesisConfig::<$test> { +// balances: vec![(1, 10)], +// }.assimilate_storage(&mut t).unwrap(); +// } + +// #[test] +// #[should_panic = "duplicate balances in genesis."] +// fn cannot_set_genesis_value_twice() { +// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); +// let _ = pallet_balances::GenesisConfig::<$test> { +// balances: vec![(1, 10), (2, 20), (1, 15)], +// }.assimilate_storage(&mut t).unwrap(); +// } + +// #[test] +// fn dust_moves_between_free_and_reserved() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// // Set balance to free and reserved at the existential deposit +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); +// // Check balance +// assert_eq!(Balances::free_balance(1), 100); +// assert_eq!(Balances::reserved_balance(1), 0); + +// // Reserve some free balance +// assert_ok!(Balances::reserve(&1, 50)); +// // Check balance, the account should be ok. +// assert_eq!(Balances::free_balance(1), 50); +// assert_eq!(Balances::reserved_balance(1), 50); + +// // Reserve the rest of the free balance +// assert_ok!(Balances::reserve(&1, 50)); +// // Check balance, the account should be ok. +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 100); + +// // Unreserve everything +// Balances::unreserve(&1, 100); +// // Check balance, all 100 should move to free_balance +// assert_eq!(Balances::free_balance(1), 100); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn account_deleted_when_just_dust() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// // Set balance to free and reserved at the existential deposit +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 50, 50)); +// // Check balance +// assert_eq!(Balances::free_balance(1), 50); +// assert_eq!(Balances::reserved_balance(1), 50); + +// // Reserve some free balance +// let res = Balances::slash(&1, 1); +// assert_eq!(res, (NegativeImbalance::new(1), 0)); + +// // The account should be dead. +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn emit_events_with_reserve_and_unreserve() { +// <$ext_builder>::default() +// .build() +// .execute_with(|| { +// let _ = Balances::deposit_creating(&1, 100); + +// System::set_block_number(2); +// assert_ok!(Balances::reserve(&1, 10)); + +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { who: 1, amount: 10 })); + +// System::set_block_number(3); +// assert!(Balances::unreserve(&1, 5).is_zero()); + +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); + +// System::set_block_number(4); +// assert_eq!(Balances::unreserve(&1, 6), 1); + +// // should only unreserve 5 +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); +// }); +// } + +// #[test] +// fn emit_events_with_existential_deposit() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), +// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), +// ] +// ); + +// let res = Balances::slash(&1, 1); +// assert_eq!(res, (NegativeImbalance::new(1), 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), +// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), +// ] +// ); +// }); +// } + +// #[test] +// fn emit_events_with_no_existential_deposit_suicide() { +// <$ext_builder>::default() +// .existential_deposit(1) +// .build() +// .execute_with(|| { +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), +// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), +// ] +// ); + +// let res = Balances::slash(&1, 100); +// assert_eq!(res, (NegativeImbalance::new(100), 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), +// ] +// ); +// }); +// } + +// #[test] +// fn slash_loop_works() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// /* User has no reference counter, so they can die in these scenarios */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 900 })); + +// // SCENARIO: Slash will kill account because not enough balance left. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); +// // Account is killed +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash will kill account, and report missing slash amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed full free_balance, and reports 300 not slashed +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); +// // Account is dead +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, but keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, and kill. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); +// // Account is dead because 50 reserved balance is not enough to keep alive +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash can take as much as possible from reserved, kill, and report missing amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); +// // Account is super dead +// assert!(!System::account_exists(&1)); + +// /* User will now have a reference counter on them, keeping them alive in these scenarios */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Slash will take as much as possible without killing account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(900), 50)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash will not kill account, and report missing slash amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed full free_balance minus ED, and reports 400 not slashed +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(900), 400)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, but keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, but keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); +// // Slashed full free_balance and 250 of reserved balance to leave ED +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take as much as possible from reserved and report missing amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1150), 150)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // Slash on non-existent account is okay. +// assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); +// }); +// } + +// #[test] +// fn slash_reserved_loop_works() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// /* User has no reference counter, so they can die in these scenarios */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Slash would kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(1_000), 0)); +// // Account is dead +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash would kill account, and reports left over slash. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); +// // Account is dead +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash does not take from free balance. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 300, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); +// // Account is alive because of free balance +// assert!(System::account_exists(&1)); + +// /* User has a reference counter, so they cannot die */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Slash as much as possible without killing. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed as much as possible +// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(950), 50)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash reports correctly, where reserved is needed to keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed as much as possible +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(950), 350)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash reports correctly, where full reserved is removed. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 1_000)); +// // Slashed as much as possible +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // Slash on non-existent account is okay. +// assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); +// }); +// } + +// #[test] +// fn operations_on_dead_account_should_not_change_state() { +// // These functions all use `mutate_account` which may introduce a storage change when +// // the account never existed to begin with, and shouldn't exist in the end. +// <$ext_builder>::default() +// .existential_deposit(0) +// .build() +// .execute_with(|| { +// assert!(!frame_system::Account::::contains_key(&1337)); + +// // Unreserve +// assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); +// // Reserve +// assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); +// // Slash Reserve +// assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); +// // Repatriate Reserve +// assert_noop!(Balances::repatriate_reserved(&1337, &1338, 42, Status::Free), Error::::DeadAccount); +// // Slash +// assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); +// }); +// } + +// #[test] +// fn transfer_keep_alive_all_free_succeed() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 100, 100)); +// assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 100); +// }); +// } + +// #[test] +// fn transfer_all_works() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and allow death +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); +// assert_eq!(Balances::total_balance(&1), 0); +// assert_eq!(Balances::total_balance(&2), 200); + +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and keep alive +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 100); + +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and allow death w/ reserved +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); +// assert_eq!(Balances::total_balance(&1), 0); +// assert_eq!(Balances::total_balance(&2), 200); + +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and keep alive w/ reserved +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 110); +// }); +// } + +// #[test] +// fn named_reserve_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id_1 = [1u8; 8]; +// let id_2 = [2u8; 8]; +// let id_3 = [3u8; 8]; + +// // reserve + +// assert_noop!(Balances::reserve_named(&id_1, &1, 112), Error::::InsufficientBalance); + +// assert_ok!(Balances::reserve_named(&id_1, &1, 12)); + +// assert_eq!(Balances::reserved_balance(1), 12); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + +// assert_ok!(Balances::reserve_named(&id_1, &1, 2)); + +// assert_eq!(Balances::reserved_balance(1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + +// assert_ok!(Balances::reserve_named(&id_2, &1, 23)); + +// assert_eq!(Balances::reserved_balance(1), 37); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_ok!(Balances::reserve(&1, 34)); + +// assert_eq!(Balances::reserved_balance(1), 71); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 40); + +// assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); + +// // unreserve + +// assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); + +// assert_eq!(Balances::reserved_balance(1), 61); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); + +// assert_eq!(Balances::reserved_balance(1), 57); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); + +// assert_eq!(Balances::reserved_balance(1), 54); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 57); + +// // slash_reserved_named + +// assert_ok!(Balances::reserve_named(&id_1, &1, 10)); + +// assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); + +// assert_eq!(Balances::reserved_balance(1), 54); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); +// assert_eq!(Balances::total_balance(&1), 101); + +// assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); + +// assert_eq!(Balances::reserved_balance(1), 49); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); +// assert_eq!(Balances::total_balance(&1), 96); + +// // repatriate_reserved_named + +// let _ = Balances::deposit_creating(&2, 100); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Reserved).unwrap(), 0); + +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); +// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); +// assert_eq!(Balances::reserved_balance(&2), 10); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Status::Reserved).unwrap(), 1); + +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); +// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); +// assert_eq!(Balances::reserved_balance(&2), 0); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Free).unwrap(), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); +// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); +// assert_eq!(Balances::free_balance(&2), 110); + +// // repatriate_reserved_named to self + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Status::Reserved).unwrap(), 5); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + +// assert_eq!(Balances::free_balance(&1), 47); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Status::Free).unwrap(), 10); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + +// assert_eq!(Balances::free_balance(&1), 52); +// }); +// } + +// #[test] +// fn reserved_named_to_yourself_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 50)); +// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Status::Free), 0); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + +// assert_ok!(Balances::reserve_named(&id, &1, 50)); +// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Status::Free), 10); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// }); +// } + +// #[test] +// fn ensure_reserved_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 15); + +// assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 10); + +// assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 20); +// }); +// } + +// #[test] +// fn unreserve_all_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 15)); + +// assert_eq!(Balances::unreserve_all_named(&id, &1), 15); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// assert_eq!(Balances::free_balance(&1), 111); + +// assert_eq!(Balances::unreserve_all_named(&id, &1), 0); +// }); +// } + +// #[test] +// fn slash_all_reserved_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 15)); + +// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// assert_eq!(Balances::free_balance(&1), 96); + +// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); +// }); +// } + +// #[test] +// fn repatriate_all_reserved_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// let _ = Balances::deposit_creating(&2, 10); +// let _ = Balances::deposit_creating(&3, 10); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 15)); + +// assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Status::Reserved)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id, &2), 15); + +// assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Status::Free)); +// assert_eq!(Balances::reserved_balance_named(&id, &2), 0); +// assert_eq!(Balances::free_balance(&3), 25); +// }); +// } + +// #[test] +// fn set_balance_handles_killing_account() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(frame_system::Pallet::::inc_consumers(&1)); +// assert_noop!( +// Balances::set_balance(RuntimeOrigin::root(), 1, 0, 0), +// DispatchError::ConsumerRemaining, +// ); +// }); +// } + +// #[test] +// fn set_balance_handles_total_issuance() { +// <$ext_builder>::default().build().execute_with(|| { +// let old_total_issuance = Balances::total_issuance(); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1337, 69, 42)); +// assert_eq!(Balances::total_issuance(), old_total_issuance + 69 + 42); +// assert_eq!(Balances::total_balance(&1337), 69 + 42); +// assert_eq!(Balances::free_balance(&1337), 69); +// assert_eq!(Balances::reserved_balance(&1337), 42); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_set_balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_eq!(>::balance(&1337), 0); +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!(>::balance(&1337), 100); + +// assert_ok!(Balances::reserve(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); + +// assert_noop!(>::set_balance(&1337, 0), ArithmeticError::Underflow); + +// assert_ok!(>::set_balance(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 0); +// assert_eq!(Balances::reserved_balance(1337), 60); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_set_total_issuance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_eq!(>::total_issuance(), 0); +// >::set_total_issuance(100); +// assert_eq!(>::total_issuance(), 100); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_decrease_balance_simple_works() { +// <$ext_builder>::default().build().execute_with(|| { +// // An Account that starts at 100 +// assert_ok!(>::set_balance(&1337, 100)); +// // and reserves 50 +// assert_ok!(Balances::reserve(&1337, 50)); +// // and is decreased by 20 +// assert_ok!(>::decrease_balance(&1337, 20)); +// // should end up at 80. +// assert_eq!(>::balance(&1337), 80); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_decrease_balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!(>::balance(&1337), 100); + +// assert_noop!( +// >::decrease_balance(&1337, 101), +// TokenError::NoFunds +// ); +// assert_eq!( +// >::decrease_balance(&1337, 100), +// Ok(100) +// ); +// assert_eq!(>::balance(&1337), 0); + +// // free: 40, reserved: 60 +// assert_ok!(>::set_balance(&1337, 100)); +// assert_ok!(Balances::reserve(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); +// assert_noop!( +// >::decrease_balance(&1337, 41), +// TokenError::NoFunds +// ); +// assert_eq!( +// >::decrease_balance(&1337, 40), +// Ok(40) +// ); +// assert_eq!(>::balance(&1337), 60); +// assert_eq!(Balances::free_balance(1337), 0); +// assert_eq!(Balances::reserved_balance(1337), 60); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_decrease_balance_at_most_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!(>::balance(&1337), 100); + +// assert_eq!( +// >::decrease_balance_at_most(&1337, 101), +// 100 +// ); +// assert_eq!(>::balance(&1337), 0); + +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 100), +// 100 +// ); +// assert_eq!(>::balance(&1337), 0); + +// // free: 40, reserved: 60 +// assert_ok!(>::set_balance(&1337, 100)); +// assert_ok!(Balances::reserve(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 0), +// 0 +// ); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 10), +// 10 +// ); +// assert_eq!(Balances::free_balance(1337), 30); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 200), +// 30 +// ); +// assert_eq!(>::balance(&1337), 60); +// assert_eq!(Balances::free_balance(1337), 0); +// assert_eq!(Balances::reserved_balance(1337), 60); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_increase_balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_noop!( +// >::increase_balance(&1337, 0), +// TokenError::BelowMinimum +// ); +// assert_eq!( +// >::increase_balance(&1337, 1), +// Ok(1) +// ); +// assert_noop!( +// >::increase_balance(&1337, u64::MAX), +// ArithmeticError::Overflow +// ); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_increase_balance_at_most_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_eq!( +// >::increase_balance_at_most(&1337, 0), +// 0 +// ); +// assert_eq!( +// >::increase_balance_at_most(&1337, 1), +// 1 +// ); +// assert_eq!( +// >::increase_balance_at_most(&1337, u64::MAX), +// u64::MAX - 1 +// ); +// }); +// } +// } +// } diff --git a/pallets/balances/src/tests_composite.rs b/pallets/balances/src/tests_composite.rs new file mode 100644 index 000000000..07e3232fb --- /dev/null +++ b/pallets/balances/src/tests_composite.rs @@ -0,0 +1,149 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2018-2022 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 + +// #![cfg(test)] + +// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; +// use frame_support::{ +// dispatch::DispatchInfo, +// parameter_types, +// traits::{ConstU32, ConstU64, ConstU8}, +// weights::{IdentityFee, Weight}, +// }; +// use pallet_transaction_payment::CurrencyAdapter; +// use sp_core::H256; +// use sp_io; +// use sp_runtime::{testing::Header, traits::IdentityLookup}; +// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +// type Block = frame_system::mocking::MockBlock; + +// frame_support::construct_runtime!( +// pub enum Test where +// Block = Block, +// NodeBlock = Block, +// UncheckedExtrinsic = UncheckedExtrinsic, +// { +// System: frame_system::{Pallet, Call, Config, Storage, Event}, +// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, +// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, +// } +// ); + +// parameter_types! { +// pub BlockWeights: frame_system::limits::BlockWeights = +// frame_system::limits::BlockWeights::simple_max( +// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), +// ); +// pub static ExistentialDeposit: u64 = 0; +// } +// impl frame_system::Config for Test { +// type BaseCallFilter = frame_support::traits::Everything; +// type BlockWeights = BlockWeights; +// type BlockLength = (); +// type DbWeight = (); +// type RuntimeOrigin = RuntimeOrigin; +// type Index = u64; +// type BlockNumber = u64; +// type RuntimeCall = RuntimeCall; +// type Hash = H256; +// type Hashing = ::sp_runtime::traits::BlakeTwo256; +// type AccountId = u64; +// type Lookup = IdentityLookup; +// type Header = Header; +// type RuntimeEvent = RuntimeEvent; +// type BlockHashCount = ConstU64<250>; +// type Version = (); +// type PalletInfo = PalletInfo; +// type AccountData = super::AccountData; +// type OnNewAccount = (); +// type OnKilledAccount = (); +// type SystemWeightInfo = (); +// type SS58Prefix = (); +// type OnSetCode = (); +// type MaxConsumers = frame_support::traits::ConstU32<16>; +// } + +// impl pallet_transaction_payment::Config for Test { +// type RuntimeEvent = RuntimeEvent; +// type OnChargeTransaction = CurrencyAdapter, ()>; +// type OperationalFeeMultiplier = ConstU8<5>; +// type WeightToFee = IdentityFee; +// type LengthToFee = IdentityFee; +// type FeeMultiplierUpdate = (); +// } + +// impl Config for Test { +// type Balance = u64; +// type DustRemoval = (); +// type RuntimeEvent = RuntimeEvent; +// type ExistentialDeposit = ExistentialDeposit; +// type AccountStore = frame_system::Pallet; +// type MaxLocks = (); +// type MaxReserves = ConstU32<2>; +// type ReserveIdentifier = [u8; 8]; +// type WeightInfo = (); +// } + +// pub struct ExtBuilder { +// existential_deposit: u64, +// monied: bool, +// } +// impl Default for ExtBuilder { +// fn default() -> Self { +// Self { existential_deposit: 1, monied: false } +// } +// } +// impl ExtBuilder { +// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { +// self.existential_deposit = existential_deposit; +// self +// } +// pub fn monied(mut self, monied: bool) -> Self { +// self.monied = monied; +// self +// } +// pub fn set_associated_consts(&self) { +// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); +// } +// pub fn build(self) -> sp_io::TestExternalities { +// self.set_associated_consts(); +// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); +// pallet_balances::GenesisConfig:: { +// balances: if self.monied { +// vec![ +// (1, 10 * self.existential_deposit), +// (2, 20 * self.existential_deposit), +// (3, 30 * self.existential_deposit), +// (4, 40 * self.existential_deposit), +// (12, 10 * self.existential_deposit), +// ] +// } else { +// vec![] +// }, +// } +// .assimilate_storage(&mut t) +// .unwrap(); + +// let mut ext = sp_io::TestExternalities::new(t); +// ext.execute_with(|| System::set_block_number(1)); +// ext +// } +// } + +// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } diff --git a/pallets/balances/src/tests_local.rs b/pallets/balances/src/tests_local.rs new file mode 100644 index 000000000..4f2cd2483 --- /dev/null +++ b/pallets/balances/src/tests_local.rs @@ -0,0 +1,191 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2018-2022 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 + +// #![cfg(test)] + +// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; +// use frame_support::{ +// dispatch::DispatchInfo, +// parameter_types, +// traits::{ConstU32, ConstU64, ConstU8, StorageMapShim}, +// weights::{IdentityFee, Weight}, +// }; +// use pallet_transaction_payment::CurrencyAdapter; +// use sp_core::H256; +// use sp_io; +// use sp_runtime::{testing::Header, traits::IdentityLookup}; + +// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +// type Block = frame_system::mocking::MockBlock; + +// frame_support::construct_runtime!( +// pub struct Test where +// Block = Block, +// NodeBlock = Block, +// UncheckedExtrinsic = UncheckedExtrinsic, +// { +// System: frame_system::{Pallet, Call, Config, Storage, Event}, +// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, +// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, +// } +// ); + +// parameter_types! { +// pub BlockWeights: frame_system::limits::BlockWeights = +// frame_system::limits::BlockWeights::simple_max( +// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), +// ); +// pub static ExistentialDeposit: u64 = 0; +// } +// impl frame_system::Config for Test { +// type BaseCallFilter = frame_support::traits::Everything; +// type BlockWeights = BlockWeights; +// type BlockLength = (); +// type DbWeight = (); +// type RuntimeOrigin = RuntimeOrigin; +// type Index = u64; +// type BlockNumber = u64; +// type RuntimeCall = RuntimeCall; +// type Hash = H256; +// type Hashing = ::sp_runtime::traits::BlakeTwo256; +// type AccountId = u64; +// type Lookup = IdentityLookup; +// type Header = Header; +// type RuntimeEvent = RuntimeEvent; +// type BlockHashCount = ConstU64<250>; +// type Version = (); +// type PalletInfo = PalletInfo; +// type AccountData = (); +// type OnNewAccount = (); +// type OnKilledAccount = (); +// type SystemWeightInfo = (); +// type SS58Prefix = (); +// type OnSetCode = (); +// type MaxConsumers = frame_support::traits::ConstU32<16>; +// } + +// impl pallet_transaction_payment::Config for Test { +// type RuntimeEvent = RuntimeEvent; +// type OnChargeTransaction = CurrencyAdapter, ()>; +// type OperationalFeeMultiplier = ConstU8<5>; +// type WeightToFee = IdentityFee; +// type LengthToFee = IdentityFee; +// type FeeMultiplierUpdate = (); +// } + +// impl Config for Test { +// type Balance = u64; +// type DustRemoval = (); +// type RuntimeEvent = RuntimeEvent; +// type ExistentialDeposit = ExistentialDeposit; +// type AccountStore = +// StorageMapShim, system::Provider, u64, super::AccountData>; +// type MaxLocks = ConstU32<50>; +// type MaxReserves = ConstU32<2>; +// type ReserveIdentifier = [u8; 8]; +// type WeightInfo = (); +// } + +// pub struct ExtBuilder { +// existential_deposit: u64, +// monied: bool, +// } +// impl Default for ExtBuilder { +// fn default() -> Self { +// Self { existential_deposit: 1, monied: false } +// } +// } +// impl ExtBuilder { +// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { +// self.existential_deposit = existential_deposit; +// self +// } +// pub fn monied(mut self, monied: bool) -> Self { +// self.monied = monied; +// if self.existential_deposit == 0 { +// self.existential_deposit = 1; +// } +// self +// } +// pub fn set_associated_consts(&self) { +// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); +// } +// pub fn build(self) -> sp_io::TestExternalities { +// self.set_associated_consts(); +// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); +// pallet_balances::GenesisConfig:: { +// balances: if self.monied { +// vec![ +// (1, 10 * self.existential_deposit), +// (2, 20 * self.existential_deposit), +// (3, 30 * self.existential_deposit), +// (4, 40 * self.existential_deposit), +// (12, 10 * self.existential_deposit), +// ] +// } else { +// vec![] +// }, +// } +// .assimilate_storage(&mut t) +// .unwrap(); + +// let mut ext = sp_io::TestExternalities::new(t); +// ext.execute_with(|| System::set_block_number(1)); +// ext +// } +// } + +// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } + +// #[test] +// fn emit_events_with_no_existential_deposit_suicide_with_dust() { +// ::default().existential_deposit(2).build().execute_with(|| { +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), +// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), +// ] +// ); + +// let res = Balances::slash(&1, 98); +// assert_eq!(res, (NegativeImbalance::new(98), 0)); + +// // no events +// assert_eq!( +// events(), +// [RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 98 })] +// ); + +// let res = Balances::slash(&1, 1); +// assert_eq!(res, (NegativeImbalance::new(1), 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 1 }), +// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }) +// ] +// ); +// }); +// } diff --git a/pallets/balances/src/tests_reentrancy.rs b/pallets/balances/src/tests_reentrancy.rs new file mode 100644 index 000000000..61814e598 --- /dev/null +++ b/pallets/balances/src/tests_reentrancy.rs @@ -0,0 +1,264 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2018-2022 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 setup for potential reentracy and lost updates of nested mutations. + +// #![cfg(test)] + +// use crate::{self as pallet_balances, Config}; +// use frame_support::{ +// parameter_types, +// traits::{ConstU32, ConstU64, StorageMapShim}, +// }; +// use sp_core::H256; +// use sp_io; +// use sp_runtime::{testing::Header, traits::IdentityLookup}; + +// use crate::*; +// use frame_support::{ +// assert_ok, +// traits::{Currency, ReservableCurrency}, +// }; +// use frame_system::RawOrigin; + +// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +// type Block = frame_system::mocking::MockBlock; + +// frame_support::construct_runtime!( +// pub enum Test where +// Block = Block, +// NodeBlock = Block, +// UncheckedExtrinsic = UncheckedExtrinsic, +// { +// System: frame_system::{Pallet, Call, Config, Storage, Event}, +// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, +// } +// ); + +// parameter_types! { +// pub BlockWeights: frame_system::limits::BlockWeights = +// frame_system::limits::BlockWeights::simple_max( +// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), +// ); +// pub static ExistentialDeposit: u64 = 0; +// } +// impl frame_system::Config for Test { +// type BaseCallFilter = frame_support::traits::Everything; +// type BlockWeights = BlockWeights; +// type BlockLength = (); +// type DbWeight = (); +// type RuntimeOrigin = RuntimeOrigin; +// type Index = u64; +// type BlockNumber = u64; +// type RuntimeCall = RuntimeCall; +// type Hash = H256; +// type Hashing = ::sp_runtime::traits::BlakeTwo256; +// type AccountId = u64; +// type Lookup = IdentityLookup; +// type Header = Header; +// type RuntimeEvent = RuntimeEvent; +// type BlockHashCount = ConstU64<250>; +// type Version = (); +// type PalletInfo = PalletInfo; +// type AccountData = (); +// type OnNewAccount = (); +// type OnKilledAccount = (); +// type SystemWeightInfo = (); +// type SS58Prefix = (); +// type OnSetCode = (); +// type MaxConsumers = frame_support::traits::ConstU32<16>; +// } + +// pub struct OnDustRemoval; +// impl OnUnbalanced> for OnDustRemoval { +// fn on_nonzero_unbalanced(amount: NegativeImbalance) { +// assert_ok!(Balances::resolve_into_existing(&1, amount)); +// } +// } + +// impl Config for Test { +// type Balance = u64; +// type DustRemoval = OnDustRemoval; +// type RuntimeEvent = RuntimeEvent; +// type ExistentialDeposit = ExistentialDeposit; +// type AccountStore = +// StorageMapShim, system::Provider, u64, super::AccountData>; +// type MaxLocks = ConstU32<50>; +// type MaxReserves = ConstU32<2>; +// type ReserveIdentifier = [u8; 8]; +// type WeightInfo = (); +// } + +// pub struct ExtBuilder { +// existential_deposit: u64, +// } +// impl Default for ExtBuilder { +// fn default() -> Self { +// Self { existential_deposit: 1 } +// } +// } +// impl ExtBuilder { +// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { +// self.existential_deposit = existential_deposit; +// self +// } + +// pub fn set_associated_consts(&self) { +// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); +// } + +// pub fn build(self) -> sp_io::TestExternalities { +// self.set_associated_consts(); +// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); +// pallet_balances::GenesisConfig:: { balances: vec![] } +// .assimilate_storage(&mut t) +// .unwrap(); +// let mut ext = sp_io::TestExternalities::new(t); +// ext.execute_with(|| System::set_block_number(1)); +// ext +// } +// } + +// #[test] +// fn transfer_dust_removal_tst1_should_work() { +// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { +// // Verification of reentrancy in dust removal +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + +// // In this transaction, account 2 free balance +// // drops below existential balance +// // and dust balance is removed from account 2 +// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 3, 450)); + +// // As expected dust balance is removed. +// assert_eq!(Balances::free_balance(&2), 0); + +// // As expected beneficiary account 3 +// // received the transfered fund. +// assert_eq!(Balances::free_balance(&3), 450); + +// // Dust balance is deposited to account 1 +// // during the process of dust removal. +// assert_eq!(Balances::free_balance(&1), 1050); + +// // Verify the events +// assert_eq!(System::events().len(), 12); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { +// from: 2, +// to: 3, +// amount: 450, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { +// account: 2, +// amount: 50, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { +// who: 1, +// amount: 50, +// })); +// }); +// } + +// #[test] +// fn transfer_dust_removal_tst2_should_work() { +// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { +// // Verification of reentrancy in dust removal +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + +// // In this transaction, account 2 free balance +// // drops below existential balance +// // and dust balance is removed from account 2 +// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 1, 450)); + +// // As expected dust balance is removed. +// assert_eq!(Balances::free_balance(&2), 0); + +// // Dust balance is deposited to account 1 +// // during the process of dust removal. +// assert_eq!(Balances::free_balance(&1), 1500); + +// // Verify the events +// assert_eq!(System::events().len(), 10); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { +// from: 2, +// to: 1, +// amount: 450, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { +// account: 2, +// amount: 50, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { +// who: 1, +// amount: 50, +// })); +// }); +// } + +// #[test] +// fn repatriating_reserved_balance_dust_removal_should_work() { +// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { +// // Verification of reentrancy in dust removal +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + +// // Reserve a value on account 2, +// // Such that free balance is lower than +// // Exestintial deposit. +// assert_ok!(Balances::reserve(&2, 450)); + +// // Transfer of reserved fund from slashed account 2 to +// // beneficiary account 1 +// assert_ok!(Balances::repatriate_reserved(&2, &1, 450, Status::Free), 0); + +// // Since free balance of account 2 is lower than +// // existential deposit, dust amount is +// // removed from the account 2 +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::free_balance(2), 0); + +// // account 1 is credited with reserved amount +// // together with dust balance during dust +// // removal. +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(Balances::free_balance(1), 1500); + +// // Verify the events +// assert_eq!(System::events().len(), 11); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { +// from: 2, +// to: 1, +// amount: 450, +// destination_status: Status::Free, +// })); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { +// account: 2, +// amount: 50, +// })); + +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { +// who: 1, +// amount: 50, +// })); +// }); +// } diff --git a/pallets/balances/src/weights.rs b/pallets/balances/src/weights.rs new file mode 100644 index 000000000..6324745fd --- /dev/null +++ b/pallets/balances/src/weights.rs @@ -0,0 +1,164 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 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 pallet_balances +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-11-07, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bm2`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/substrate +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/balances/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_balances. +pub trait WeightInfo { + fn transfer() -> Weight; + fn transfer_keep_alive() -> Weight; + fn set_balance_creating() -> Weight; + fn set_balance_killing() -> Weight; + fn force_transfer() -> Weight; + fn transfer_all() -> Weight; + fn force_unreserve() -> Weight; +} + +/// Weights for pallet_balances using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: System Account (r:1 w:1) + fn transfer() -> Weight { + // Minimum execution time: 48_134 nanoseconds. + Weight::from_ref_time(48_811_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_keep_alive() -> Weight { + // Minimum execution time: 36_586 nanoseconds. + Weight::from_ref_time(36_966_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_creating() -> Weight { + // Minimum execution time: 28_486 nanoseconds. + Weight::from_ref_time(28_940_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_killing() -> Weight { + // Minimum execution time: 31_225 nanoseconds. + Weight::from_ref_time(31_946_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:2 w:2) + fn force_transfer() -> Weight { + // Minimum execution time: 47_347 nanoseconds. + Weight::from_ref_time(48_005_000 as u64) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(2 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_all() -> Weight { + // Minimum execution time: 41_668 nanoseconds. + Weight::from_ref_time(42_232_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_unreserve() -> Weight { + // Minimum execution time: 23_741 nanoseconds. + Weight::from_ref_time(24_073_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: System Account (r:1 w:1) + fn transfer() -> Weight { + // Minimum execution time: 48_134 nanoseconds. + Weight::from_ref_time(48_811_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_keep_alive() -> Weight { + // Minimum execution time: 36_586 nanoseconds. + Weight::from_ref_time(36_966_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_creating() -> Weight { + // Minimum execution time: 28_486 nanoseconds. + Weight::from_ref_time(28_940_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_killing() -> Weight { + // Minimum execution time: 31_225 nanoseconds. + Weight::from_ref_time(31_946_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:2 w:2) + fn force_transfer() -> Weight { + // Minimum execution time: 47_347 nanoseconds. + Weight::from_ref_time(48_005_000 as u64) + .saturating_add(RocksDbWeight::get().reads(2 as u64)) + .saturating_add(RocksDbWeight::get().writes(2 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_all() -> Weight { + // Minimum execution time: 41_668 nanoseconds. + Weight::from_ref_time(42_232_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_unreserve() -> Weight { + // Minimum execution time: 23_741 nanoseconds. + Weight::from_ref_time(24_073_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } +} diff --git a/pallets/collator-selection/Cargo.toml b/pallets/collator-selection/Cargo.toml index 9b1fafb47..4a8a792a6 100644 --- a/pallets/collator-selection/Cargo.toml +++ b/pallets/collator-selection/Cargo.toml @@ -33,7 +33,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] manta-primitives = { path = "../../primitives/manta" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-consensus-aura = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index ae8d1e369..5ac208f4c 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -17,7 +17,7 @@ scale-info = { version = "2.3.1", default-features = false, features = ["derive" frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false, optional = true } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +pallet-balances = { path = "../balances", default-features = false } sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } @@ -31,7 +31,7 @@ xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "release-v0 [dev-dependencies] pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index 078f748f1..58a2813a7 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -126,7 +126,7 @@ manta-crypto = { git = "https://github.com/manta-network/manta-rs.git", tag = "v manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["groth16", "parameters", "scale", "download", "test"] } pallet-asset-manager = { path = "../asset-manager" } pallet-assets = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } pallet-tx-pause = { path = '../tx-pause' } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/manta-sbt/Cargo.toml b/pallets/manta-sbt/Cargo.toml index 80792ad2e..6e4c22683 100644 --- a/pallets/manta-sbt/Cargo.toml +++ b/pallets/manta-sbt/Cargo.toml @@ -129,7 +129,7 @@ manta-crypto = { git = "https://github.com/manta-network/manta-rs.git", tag = "v manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["groth16", "parameters", "scale", "download", "test"] } pallet-asset-manager = { path = "../asset-manager" } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } pallet-manta-pay = { path = "../manta-pay" } pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-tx-pause = { path = "../tx-pause" } diff --git a/pallets/name-service/Cargo.toml b/pallets/name-service/Cargo.toml index edffe4cf3..64857014b 100644 --- a/pallets/name-service/Cargo.toml +++ b/pallets/name-service/Cargo.toml @@ -22,7 +22,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "po sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false } [dev-dependencies] -pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/pallet-lottery/Cargo.toml b/pallets/pallet-lottery/Cargo.toml index 3e04c15e2..8fa374854 100644 --- a/pallets/pallet-lottery/Cargo.toml +++ b/pallets/pallet-lottery/Cargo.toml @@ -40,7 +40,7 @@ rand = { version = "0.8.5", default-features = false, optional = true } calamari-runtime = { path = "../../runtime/calamari", default-features = false } lazy_static = "1.4.0" manta-collator-selection = { path = "../collator-selection", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } pallet-preimage = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-randomness = { path = '../randomness', default-features = false } pallet-scheduler = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/parachain-staking/Cargo.toml b/pallets/parachain-staking/Cargo.toml index 41c3bf00b..726e0f7ae 100644 --- a/pallets/parachain-staking/Cargo.toml +++ b/pallets/parachain-staking/Cargo.toml @@ -33,7 +33,7 @@ sp-staking = { git = 'https://github.com/paritytech/substrate.git', default-feat [dev-dependencies] similar-asserts = "1.1.0" -pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/randomness/Cargo.toml b/pallets/randomness/Cargo.toml index 000f52e6d..026766901 100644 --- a/pallets/randomness/Cargo.toml +++ b/pallets/randomness/Cargo.toml @@ -27,7 +27,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkad [dev-dependencies] derive_more = "0.99" -pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", features = ["std"] } +pallet-balances = { path = "../balances", features = ["std"]} [features] default = ["std"] diff --git a/pallets/tx-pause/Cargo.toml b/pallets/tx-pause/Cargo.toml index 45b20d484..99da3ae84 100644 --- a/pallets/tx-pause/Cargo.toml +++ b/pallets/tx-pause/Cargo.toml @@ -18,7 +18,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad [dev-dependencies] manta-primitives = { path = '../../primitives/manta' } -pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/vesting/Cargo.toml b/pallets/vesting/Cargo.toml index 3856c741b..36330253f 100644 --- a/pallets/vesting/Cargo.toml +++ b/pallets/vesting/Cargo.toml @@ -14,7 +14,7 @@ scale-info = { version = "2.1.2", default-features = false, features = ["derive" frame-benchmarking = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37", optional = true } frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37", optional = true } +pallet-balances = { path = "../balances", default-features = false } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37", optional = true } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } @@ -22,7 +22,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] chrono = "0.4" manta-primitives = { path = "../../primitives/manta" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index d6cf61286..46f478bd2 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -44,7 +44,7 @@ frame-try-runtime = { git = "https://github.com/paritytech/substrate.git", defau pallet-assets = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } pallet-authorship = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../../pallets/balances", default-features = false } pallet-collective = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } pallet-democracy = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } pallet-membership = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 76a89e73a..17d74e937 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -30,7 +30,7 @@ scale-info = { version = "2.1.2", features = ["derive"] } # Substrate dependencies frame-system = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } pallet-assets = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../../pallets/balances" } pallet-utility = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index b3d1e6b5a..4f30200ac 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -18,7 +18,7 @@ frame-support = { git = 'https://github.com/paritytech/substrate.git', branch = frame-system = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } lazy_static = "1.4.0" pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../../pallets/balances" } pallet-collective = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } pallet-democracy = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } pallet-membership = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index 0b88d3b3f..c68884ef5 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -44,7 +44,7 @@ frame-try-runtime = { git = "https://github.com/paritytech/substrate.git", defau pallet-assets = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } pallet-authorship = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../../pallets/balances", default-features = false } pallet-collective = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } pallet-democracy = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } pallet-membership = { git = "https://github.com/paritytech/substrate.git", default-features = false, branch = "polkadot-v0.9.37" } From 0fea396f6c915721e06e93cbbd4fc9c8601286f7 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 11 Aug 2023 12:49:27 +0300 Subject: [PATCH 02/69] Add barrier code to pallet-balances and update all runtimes Signed-off-by: Georgi Zlatarev --- pallets/asset-manager/src/mock.rs | 8 + pallets/balances/src/lib.rs | 3877 +++++++++-------- pallets/collator-selection/src/mock.rs | 1 + pallets/farming/src/mock.rs | 8 + pallets/manta-pay/src/mock.rs | 8 + pallets/manta-sbt/src/mock.rs | 8 + pallets/name-service/src/mock.rs | 8 + pallets/pallet-lottery/src/mock.rs | 8 + pallets/parachain-staking/src/mock.rs | 7 + pallets/randomness/src/mock.rs | 7 + pallets/tx-pause/src/mock.rs | 8 + pallets/vesting/src/mock.rs | 1 + runtime/calamari/src/lib.rs | 3 +- .../src/integrations_mock/test_calamari.rs | 14 + .../src/integrations_mock/test_manta.rs | 14 + .../src/xcm_mock/parachain.rs | 8 + .../src/xcm_mock/relay_chain.rs | 8 + runtime/manta/src/lib.rs | 3 +- 18 files changed, 2159 insertions(+), 1840 deletions(-) diff --git a/pallets/asset-manager/src/mock.rs b/pallets/asset-manager/src/mock.rs index ed2b4ec94..6509a24fc 100644 --- a/pallets/asset-manager/src/mock.rs +++ b/pallets/asset-manager/src/mock.rs @@ -115,6 +115,13 @@ parameter_types! { pub const MaxReserves: u32 = 50; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + impl pallet_balances::Config for Runtime { type MaxLocks = MaxLocks; type Balance = Balance; @@ -125,6 +132,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; + type UnixTime = MockUnixTime; } pub struct MantaAssetRegistry; diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 99d77a3e7..567a020c0 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -168,25 +168,25 @@ use codec::{Codec, Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] use frame_support::traits::GenesisBuild; use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - traits::{ - tokens::{fungible, BalanceStatus as Status, DepositConsequence, WithdrawConsequence}, - Currency, DefensiveSaturating, ExistenceRequirement, - ExistenceRequirement::{AllowDeath, KeepAlive}, - Get, Imbalance, LockIdentifier, LockableCurrency, NamedReservableCurrency, OnUnbalanced, - ReservableCurrency, SignedImbalance, StoredMap, TryDrop, WithdrawReasons, - }, - WeakBoundedVec, + ensure, + pallet_prelude::DispatchResult, + traits::{ + tokens::{fungible, BalanceStatus as Status, DepositConsequence, WithdrawConsequence}, + Currency, DefensiveSaturating, ExistenceRequirement, + ExistenceRequirement::{AllowDeath, KeepAlive}, + Get, Imbalance, LockIdentifier, LockableCurrency, NamedReservableCurrency, OnUnbalanced, + ReservableCurrency, SignedImbalance, StoredMap, TryDrop, UnixTime, WithdrawReasons, + }, + WeakBoundedVec, }; use frame_system as system; use scale_info::TypeInfo; use sp_runtime::{ - traits::{ - AtLeast32BitUnsigned, Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, - Saturating, StaticLookup, Zero, - }, - ArithmeticError, DispatchError, FixedPointOperand, RuntimeDebug, + traits::{ + AtLeast32BitUnsigned, Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, + Saturating, StaticLookup, Zero, + }, + ArithmeticError, DispatchError, FixedPointOperand, RuntimeDebug, }; use sp_std::{cmp, fmt::Debug, mem, ops::BitOr, prelude::*, result}; pub use weights::WeightInfo; @@ -199,1394 +199,1537 @@ type AccountIdLookupOf = <::Lookup as StaticLookup #[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 balance of an account. - type Balance: Parameter - + Member - + AtLeast32BitUnsigned - + Codec - + Default - + Copy - + MaybeSerializeDeserialize - + Debug - + MaxEncodedLen - + TypeInfo - + FixedPointOperand; - - /// Handler for the unbalanced reduction when removing a dust account. - type DustRemoval: OnUnbalanced>; - - /// The overarching event type. - type RuntimeEvent: From> - + IsType<::RuntimeEvent>; - - /// The minimum amount required to keep an account open. - #[pallet::constant] - type ExistentialDeposit: Get; - - /// The means of storing the balances of an account. - type AccountStore: StoredMap>; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - - /// The maximum number of locks that should exist on an account. - /// Not strictly enforced, but used for weight estimation. - #[pallet::constant] - type MaxLocks: Get; - - /// The maximum number of named reserves that can exist on an account. - #[pallet::constant] - type MaxReserves: Get; - - /// The id type for named reserves. - type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; - } - - /// The current storage version. - const STORAGE_VERSION: frame_support::traits::StorageVersion = - frame_support::traits::StorageVersion::new(1); - - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - #[pallet::storage_version(STORAGE_VERSION)] - pub struct Pallet(PhantomData<(T, I)>); - - #[pallet::call] - impl, I: 'static> Pallet { - /// Transfer some liquid free balance to another account. - /// - /// `transfer` will set the `FreeBalance` of the sender and receiver. - /// If the sender's account is below the existential deposit as a result - /// of the transfer, the account will be reaped. - /// - /// The dispatch origin for this call must be `Signed` by the transactor. - /// - /// # - /// - Dependent on arguments but not critical, given proper implementations for input config - /// types. See related functions below. - /// - It contains a limited number of reads and writes internally and no complex - /// computation. - /// - /// Related functions: - /// - /// - `ensure_can_withdraw` is always called internally but has a bounded complexity. - /// - Transferring balances to accounts that did not exist before will cause - /// `T::OnNewAccount::on_new_account` to be called. - /// - Removing enough funds from an account will trigger `T::DustRemoval::on_unbalanced`. - /// - `transfer_keep_alive` works the same way as `transfer`, but has an additional check - /// that the transfer will not kill the origin account. - /// --------------------------------- - /// - Origin account is already in memory, so no DB operations for them. - /// # - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::transfer())] - pub fn transfer( - origin: OriginFor, - dest: AccountIdLookupOf, - #[pallet::compact] value: T::Balance, - ) -> DispatchResultWithPostInfo { - let transactor = ensure_signed(origin)?; - let dest = T::Lookup::lookup(dest)?; - >::transfer( - &transactor, - &dest, - value, - ExistenceRequirement::AllowDeath, - )?; - Ok(().into()) - } - - /// Set the balances of a given account. - /// - /// This will alter `FreeBalance` and `ReservedBalance` in storage. it will - /// also alter the total issuance of the system (`TotalIssuance`) appropriately. - /// If the new free or reserved balance is below the existential deposit, - /// it will reset the account nonce (`frame_system::AccountNonce`). - /// - /// The dispatch origin for this call is `root`. - #[pallet::call_index(1)] - #[pallet::weight( + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The balance of an account. + type Balance: Parameter + + Member + + AtLeast32BitUnsigned + + Codec + + Default + + Copy + + MaybeSerializeDeserialize + + Debug + + MaxEncodedLen + + TypeInfo + + FixedPointOperand; + + /// Handler for the unbalanced reduction when removing a dust account. + type DustRemoval: OnUnbalanced>; + + /// The overarching event type. + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + + /// The minimum amount required to keep an account open. + #[pallet::constant] + type ExistentialDeposit: Get; + + /// The means of storing the balances of an account. + type AccountStore: StoredMap>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// The maximum number of locks that should exist on an account. + /// Not strictly enforced, but used for weight estimation. + #[pallet::constant] + type MaxLocks: Get; + + /// The maximum number of named reserves that can exist on an account. + #[pallet::constant] + type MaxReserves: Get; + + /// The id type for named reserves. + type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; + + /// Timestamp provider + type UnixTime: UnixTime; + } + + /// The current storage version. + const STORAGE_VERSION: frame_support::traits::StorageVersion = + frame_support::traits::StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::call] + impl, I: 'static> Pallet { + /// Transfer some liquid free balance to another account. + /// + /// `transfer` will set the `FreeBalance` of the sender and receiver. + /// If the sender's account is below the existential deposit as a result + /// of the transfer, the account will be reaped. + /// + /// The dispatch origin for this call must be `Signed` by the transactor. + /// + /// # + /// - Dependent on arguments but not critical, given proper implementations for input config + /// types. See related functions below. + /// - It contains a limited number of reads and writes internally and no complex + /// computation. + /// + /// Related functions: + /// + /// - `ensure_can_withdraw` is always called internally but has a bounded complexity. + /// - Transferring balances to accounts that did not exist before will cause + /// `T::OnNewAccount::on_new_account` to be called. + /// - Removing enough funds from an account will trigger `T::DustRemoval::on_unbalanced`. + /// - `transfer_keep_alive` works the same way as `transfer`, but has an additional check + /// that the transfer will not kill the origin account. + /// --------------------------------- + /// - Origin account is already in memory, so no DB operations for them. + /// # + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::transfer())] + pub fn transfer( + origin: OriginFor, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResultWithPostInfo { + let transactor = ensure_signed(origin)?; + let dest = T::Lookup::lookup(dest)?; + Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + >::transfer( + &transactor, + &dest, + value, + ExistenceRequirement::AllowDeath, + )?; + Ok(().into()) + } + + /// Set the balances of a given account. + /// + /// This will alter `FreeBalance` and `ReservedBalance` in storage. it will + /// also alter the total issuance of the system (`TotalIssuance`) appropriately. + /// If the new free or reserved balance is below the existential deposit, + /// it will reset the account nonce (`frame_system::AccountNonce`). + /// + /// The dispatch origin for this call is `root`. + #[pallet::call_index(1)] + #[pallet::weight( T::WeightInfo::set_balance_creating() // Creates a new account. .max(T::WeightInfo::set_balance_killing()) // Kills an existing account. )] - pub fn set_balance( - origin: OriginFor, - who: AccountIdLookupOf, - #[pallet::compact] new_free: T::Balance, - #[pallet::compact] new_reserved: T::Balance, - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - let who = T::Lookup::lookup(who)?; - let existential_deposit = T::ExistentialDeposit::get(); - - let wipeout = new_free + new_reserved < existential_deposit; - let new_free = if wipeout { Zero::zero() } else { new_free }; - let new_reserved = if wipeout { Zero::zero() } else { new_reserved }; - - // First we try to modify the account's balance to the forced balance. - let (old_free, old_reserved) = Self::mutate_account(&who, |account| { - let old_free = account.free; - let old_reserved = account.reserved; - - account.free = new_free; - account.reserved = new_reserved; - - (old_free, old_reserved) - })?; - - // This will adjust the total issuance, which was not done by the `mutate_account` - // above. - if new_free > old_free { - mem::drop(PositiveImbalance::::new(new_free - old_free)); - } else if new_free < old_free { - mem::drop(NegativeImbalance::::new(old_free - new_free)); - } - - if new_reserved > old_reserved { - mem::drop(PositiveImbalance::::new(new_reserved - old_reserved)); - } else if new_reserved < old_reserved { - mem::drop(NegativeImbalance::::new(old_reserved - new_reserved)); - } - - Self::deposit_event(Event::BalanceSet { who, free: new_free, reserved: new_reserved }); - Ok(().into()) - } - - /// Exactly as `transfer`, except the origin must be root and the source account may be - /// specified. - /// # - /// - Same as transfer, but additional read and write because the source account is not - /// assumed to be in the overlay. - /// # - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::force_transfer())] - pub fn force_transfer( - origin: OriginFor, - source: AccountIdLookupOf, - dest: AccountIdLookupOf, - #[pallet::compact] value: T::Balance, - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - let source = T::Lookup::lookup(source)?; - let dest = T::Lookup::lookup(dest)?; - >::transfer( - &source, - &dest, - value, - ExistenceRequirement::AllowDeath, - )?; - Ok(().into()) - } - - /// Same as the [`transfer`] call, but with a check that the transfer will not kill the - /// origin account. - /// - /// 99% of the time you want [`transfer`] instead. - /// - /// [`transfer`]: struct.Pallet.html#method.transfer - #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::transfer_keep_alive())] - pub fn transfer_keep_alive( - origin: OriginFor, - dest: AccountIdLookupOf, - #[pallet::compact] value: T::Balance, - ) -> DispatchResultWithPostInfo { - let transactor = ensure_signed(origin)?; - let dest = T::Lookup::lookup(dest)?; - >::transfer(&transactor, &dest, value, KeepAlive)?; - Ok(().into()) - } - - /// Transfer the entire transferable balance from the caller account. - /// - /// NOTE: This function only attempts to transfer _transferable_ balances. This means that - /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be - /// transferred by this function. To ensure that this function results in a killed account, - /// you might need to prepare the account by removing any reference counters, storage - /// deposits, etc... - /// - /// The dispatch origin of this call must be Signed. - /// - /// - `dest`: The recipient of the transfer. - /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all - /// of the funds the account has, causing the sender account to be killed (false), or - /// transfer everything except at least the existential deposit, which will guarantee to - /// keep the sender account alive (true). # - /// - O(1). Just like transfer, but reading the user's transferable balance first. - /// # - #[pallet::call_index(4)] - #[pallet::weight(T::WeightInfo::transfer_all())] - pub fn transfer_all( - origin: OriginFor, - dest: AccountIdLookupOf, - keep_alive: bool, - ) -> DispatchResult { - use fungible::Inspect; - let transactor = ensure_signed(origin)?; - let reducible_balance = Self::reducible_balance(&transactor, keep_alive); - let dest = T::Lookup::lookup(dest)?; - let keep_alive = if keep_alive { KeepAlive } else { AllowDeath }; - >::transfer(&transactor, &dest, reducible_balance, keep_alive)?; - Ok(()) - } - - /// Unreserve some balance from a user by force. - /// - /// Can only be called by ROOT. - #[pallet::call_index(5)] - #[pallet::weight(T::WeightInfo::force_unreserve())] - pub fn force_unreserve( - origin: OriginFor, - who: AccountIdLookupOf, - amount: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - let who = T::Lookup::lookup(who)?; - let _leftover = >::unreserve(&who, amount); - Ok(()) - } - } - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event, I: 'static = ()> { - /// An account was created with some free balance. - Endowed { account: T::AccountId, free_balance: T::Balance }, - /// An account was removed whose balance was non-zero but below ExistentialDeposit, - /// resulting in an outright loss. - DustLost { account: T::AccountId, amount: T::Balance }, - /// Transfer succeeded. - Transfer { from: T::AccountId, to: T::AccountId, amount: T::Balance }, - /// A balance was set by root. - BalanceSet { who: T::AccountId, free: T::Balance, reserved: T::Balance }, - /// Some balance was reserved (moved from free to reserved). - Reserved { who: T::AccountId, amount: T::Balance }, - /// Some balance was unreserved (moved from reserved to free). - Unreserved { who: T::AccountId, amount: T::Balance }, - /// Some balance was moved from the reserve of the first account to the second account. - /// Final argument indicates the destination balance type. - ReserveRepatriated { - from: T::AccountId, - to: T::AccountId, - amount: T::Balance, - destination_status: Status, - }, - /// Some amount was deposited (e.g. for transaction fees). - Deposit { who: T::AccountId, amount: T::Balance }, - /// Some amount was withdrawn from the account (e.g. for transaction fees). - Withdraw { who: T::AccountId, amount: T::Balance }, - /// Some amount was removed from the account (e.g. for misbehavior). - Slashed { who: T::AccountId, amount: T::Balance }, - } - - #[pallet::error] - pub enum Error { - /// Vesting balance too high to send value - VestingBalance, - /// Account liquidity restrictions prevent withdrawal - LiquidityRestrictions, - /// Balance too low to send value. - InsufficientBalance, - /// Value too low to create account due to existential deposit - ExistentialDeposit, - /// Transfer/payment would kill account - KeepAlive, - /// A vesting schedule already exists for this account - ExistingVestingSchedule, - /// Beneficiary account must pre-exist - DeadAccount, - /// Number of named reserves exceed MaxReserves - TooManyReserves, - } - - /// The total units issued in the system. - #[pallet::storage] - #[pallet::getter(fn total_issuance)] - #[pallet::whitelist_storage] - pub type TotalIssuance, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>; - - /// The total units of outstanding deactivated balance in the system. - #[pallet::storage] - #[pallet::getter(fn inactive_issuance)] - #[pallet::whitelist_storage] - pub type InactiveIssuance, I: 'static = ()> = - StorageValue<_, T::Balance, ValueQuery>; - - /// The Balances pallet example of storing the balance of an account. - /// - /// # Example - /// - /// ```nocompile - /// impl pallet_balances::Config for Runtime { - /// type AccountStore = StorageMapShim, frame_system::Provider, AccountId, Self::AccountData> - /// } - /// ``` - /// - /// You can also store the balance of an account in the `System` pallet. - /// - /// # Example - /// - /// ```nocompile - /// impl pallet_balances::Config for Runtime { - /// type AccountStore = System - /// } - /// ``` - /// - /// But this comes with tradeoffs, storing account balances in the system pallet stores - /// `frame_system` data alongside the account data contrary to storing account balances in the - /// `Balances` pallet, which uses a `StorageMap` to store balances data only. - /// NOTE: This is only used in the case that this pallet is used to store balances. - #[pallet::storage] - pub type Account, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, T::AccountId, AccountData, ValueQuery>; - - /// Any liquidity locks on some account balances. - /// NOTE: Should only be accessed when setting, changing and freeing a lock. - #[pallet::storage] - #[pallet::getter(fn locks)] - pub type Locks, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - WeakBoundedVec, T::MaxLocks>, - ValueQuery, - >; - - /// Named reserves on some account balances. - #[pallet::storage] - #[pallet::getter(fn reserves)] - pub type Reserves, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - BoundedVec, T::MaxReserves>, - ValueQuery, - >; - - #[pallet::genesis_config] - pub struct GenesisConfig, I: 'static = ()> { - pub balances: Vec<(T::AccountId, T::Balance)>, - } - - #[cfg(feature = "std")] - impl, I: 'static> Default for GenesisConfig { - fn default() -> Self { - Self { balances: Default::default() } - } - } - - #[pallet::genesis_build] - impl, I: 'static> GenesisBuild for GenesisConfig { - fn build(&self) { - let total = self.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n); - >::put(total); - - for (_, balance) in &self.balances { - assert!( - *balance >= >::ExistentialDeposit::get(), - "the balance of any account should always be at least the existential deposit.", - ) - } - - // ensure no duplicates exist. - let endowed_accounts = self - .balances - .iter() - .map(|(x, _)| x) - .cloned() - .collect::>(); - - assert!( - endowed_accounts.len() == self.balances.len(), - "duplicate balances in genesis." - ); - - for &(ref who, free) in self.balances.iter() { - assert!(T::AccountStore::insert(who, AccountData { free, ..Default::default() }) - .is_ok()); - } - } - } + pub fn set_balance( + origin: OriginFor, + who: AccountIdLookupOf, + #[pallet::compact] new_free: T::Balance, + #[pallet::compact] new_reserved: T::Balance, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + let existential_deposit = T::ExistentialDeposit::get(); + + let wipeout = new_free + new_reserved < existential_deposit; + let new_free = if wipeout { Zero::zero() } else { new_free }; + let new_reserved = if wipeout { Zero::zero() } else { new_reserved }; + + // First we try to modify the account's balance to the forced balance. + let (old_free, old_reserved) = Self::mutate_account(&who, |account| { + let old_free = account.free; + let old_reserved = account.reserved; + + account.free = new_free; + account.reserved = new_reserved; + + (old_free, old_reserved) + })?; + + // This will adjust the total issuance, which was not done by the `mutate_account` + // above. + if new_free > old_free { + mem::drop(PositiveImbalance::::new(new_free - old_free)); + } else if new_free < old_free { + mem::drop(NegativeImbalance::::new(old_free - new_free)); + } + + if new_reserved > old_reserved { + mem::drop(PositiveImbalance::::new(new_reserved - old_reserved)); + } else if new_reserved < old_reserved { + mem::drop(NegativeImbalance::::new(old_reserved - new_reserved)); + } + + Self::deposit_event(Event::BalanceSet { + who, + free: new_free, + reserved: new_reserved, + }); + Ok(().into()) + } + + /// Exactly as `transfer`, except the origin must be root and the source account may be + /// specified. + /// # + /// - Same as transfer, but additional read and write because the source account is not + /// assumed to be in the overlay. + /// # + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::force_transfer())] + pub fn force_transfer( + origin: OriginFor, + source: AccountIdLookupOf, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + let source = T::Lookup::lookup(source)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer( + &source, + &dest, + value, + ExistenceRequirement::AllowDeath, + )?; + Ok(().into()) + } + + /// Same as the [`transfer`] call, but with a check that the transfer will not kill the + /// origin account. + /// + /// 99% of the time you want [`transfer`] instead. + /// + /// [`transfer`]: struct.Pallet.html#method.transfer + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::transfer_keep_alive())] + pub fn transfer_keep_alive( + origin: OriginFor, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResultWithPostInfo { + let transactor = ensure_signed(origin)?; + let dest = T::Lookup::lookup(dest)?; + Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + >::transfer(&transactor, &dest, value, KeepAlive)?; + Ok(().into()) + } + + /// Transfer the entire transferable balance from the caller account. + /// + /// NOTE: This function only attempts to transfer _transferable_ balances. This means that + /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be + /// transferred by this function. To ensure that this function results in a killed account, + /// you might need to prepare the account by removing any reference counters, storage + /// deposits, etc... + /// + /// The dispatch origin of this call must be Signed. + /// + /// - `dest`: The recipient of the transfer. + /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all + /// of the funds the account has, causing the sender account to be killed (false), or + /// transfer everything except at least the existential deposit, which will guarantee to + /// keep the sender account alive (true). # + /// - O(1). Just like transfer, but reading the user's transferable balance first. + /// # + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::transfer_all())] + pub fn transfer_all( + origin: OriginFor, + dest: AccountIdLookupOf, + keep_alive: bool, + ) -> DispatchResult { + use fungible::Inspect; + let transactor = ensure_signed(origin)?; + let reducible_balance = Self::reducible_balance(&transactor, keep_alive); + let dest = T::Lookup::lookup(dest)?; + let keep_alive = if keep_alive { KeepAlive } else { AllowDeath }; + Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, reducible_balance)?; + >::transfer(&transactor, &dest, reducible_balance, keep_alive)?; + Ok(()) + } + + /// Unreserve some balance from a user by force. + /// + /// Can only be called by ROOT. + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::force_unreserve())] + pub fn force_unreserve( + origin: OriginFor, + who: AccountIdLookupOf, + amount: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + let _leftover = >::unreserve(&who, amount); + Ok(()) + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// An account was created with some free balance. + Endowed { + account: T::AccountId, + free_balance: T::Balance, + }, + /// An account was removed whose balance was non-zero but below ExistentialDeposit, + /// resulting in an outright loss. + DustLost { + account: T::AccountId, + amount: T::Balance, + }, + /// Transfer succeeded. + Transfer { + from: T::AccountId, + to: T::AccountId, + amount: T::Balance, + }, + /// A balance was set by root. + BalanceSet { + who: T::AccountId, + free: T::Balance, + reserved: T::Balance, + }, + /// Some balance was reserved (moved from free to reserved). + Reserved { + who: T::AccountId, + amount: T::Balance, + }, + /// Some balance was unreserved (moved from reserved to free). + Unreserved { + who: T::AccountId, + amount: T::Balance, + }, + /// Some balance was moved from the reserve of the first account to the second account. + /// Final argument indicates the destination balance type. + ReserveRepatriated { + from: T::AccountId, + to: T::AccountId, + amount: T::Balance, + destination_status: Status, + }, + /// Some amount was deposited (e.g. for transaction fees). + Deposit { + who: T::AccountId, + amount: T::Balance, + }, + /// Some amount was withdrawn from the account (e.g. for transaction fees). + Withdraw { + who: T::AccountId, + amount: T::Balance, + }, + /// Some amount was removed from the account (e.g. for misbehavior). + Slashed { + who: T::AccountId, + amount: T::Balance, + }, + } + + #[pallet::error] + pub enum Error { + /// Vesting balance too high to send value + VestingBalance, + /// Account liquidity restrictions prevent withdrawal + LiquidityRestrictions, + /// Balance too low to send value. + InsufficientBalance, + /// Value too low to create account due to existential deposit + ExistentialDeposit, + /// Transfer/payment would kill account + KeepAlive, + /// A vesting schedule already exists for this account + ExistingVestingSchedule, + /// Beneficiary account must pre-exist + DeadAccount, + /// Number of named reserves exceed MaxReserves + TooManyReserves, + /// + XcmTransfersLimitExceeded, + /// + XcmTransfersNotAllowedForAccount, + } + /// Stores amount of native asset XCM transfers and timestamp of last transfer + #[pallet::storage] + pub type XcmNativeTransfers, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, (T::Balance, u64), OptionQuery>; + + /// Stores limit value + #[pallet::storage] + pub type DailyXcmLimit, I: 'static = ()> = + StorageValue<_, T::Balance, OptionQuery>; + + /// The total units issued in the system. + #[pallet::storage] + #[pallet::getter(fn total_issuance)] + #[pallet::whitelist_storage] + pub type TotalIssuance, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>; + + /// The total units of outstanding deactivated balance in the system. + #[pallet::storage] + #[pallet::getter(fn inactive_issuance)] + #[pallet::whitelist_storage] + pub type InactiveIssuance, I: 'static = ()> = + StorageValue<_, T::Balance, ValueQuery>; + + /// The Balances pallet example of storing the balance of an account. + /// + /// # Example + /// + /// ```nocompile + /// impl pallet_balances::Config for Runtime { + /// type AccountStore = StorageMapShim, frame_system::Provider, AccountId, Self::AccountData> + /// } + /// ``` + /// + /// You can also store the balance of an account in the `System` pallet. + /// + /// # Example + /// + /// ```nocompile + /// impl pallet_balances::Config for Runtime { + /// type AccountStore = System + /// } + /// ``` + /// + /// But this comes with tradeoffs, storing account balances in the system pallet stores + /// `frame_system` data alongside the account data contrary to storing account balances in the + /// `Balances` pallet, which uses a `StorageMap` to store balances data only. + /// NOTE: This is only used in the case that this pallet is used to store balances. + #[pallet::storage] + pub type Account, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, AccountData, ValueQuery>; + + /// Any liquidity locks on some account balances. + /// NOTE: Should only be accessed when setting, changing and freeing a lock. + #[pallet::storage] + #[pallet::getter(fn locks)] + pub type Locks, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + WeakBoundedVec, T::MaxLocks>, + ValueQuery, + >; + + /// Named reserves on some account balances. + #[pallet::storage] + #[pallet::getter(fn reserves)] + pub type Reserves, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedVec, T::MaxReserves>, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + pub balances: Vec<(T::AccountId, T::Balance)>, + } + + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { + balances: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + let total = self + .balances + .iter() + .fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n); + >::put(total); + + for (_, balance) in &self.balances { + assert!( + *balance >= >::ExistentialDeposit::get(), + "the balance of any account should always be at least the existential deposit.", + ) + } + + // ensure no duplicates exist. + let endowed_accounts = self + .balances + .iter() + .map(|(x, _)| x) + .cloned() + .collect::>(); + + assert!( + endowed_accounts.len() == self.balances.len(), + "duplicate balances in genesis." + ); + + for &(ref who, free) in self.balances.iter() { + assert!(T::AccountStore::insert( + who, + AccountData { + free, + ..Default::default() + } + ) + .is_ok()); + } + } + } } #[cfg(feature = "std")] impl, I: 'static> GenesisConfig { - /// Direct implementation of `GenesisBuild::build_storage`. - /// - /// Kept in order not to break dependency. - pub fn build_storage(&self) -> Result { - >::build_storage(self) - } - - /// Direct implementation of `GenesisBuild::assimilate_storage`. - /// - /// Kept in order not to break dependency. - pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { - >::assimilate_storage(self, storage) - } + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + >::assimilate_storage(self, storage) + } } /// Simplified reasons for withdrawing balance. #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub enum Reasons { - /// Paying system transaction fees. - Fee = 0, - /// Any reason other than paying system transaction fees. - Misc = 1, - /// Any reason at all. - All = 2, + /// Paying system transaction fees. + Fee = 0, + /// Any reason other than paying system transaction fees. + Misc = 1, + /// Any reason at all. + All = 2, } impl From for Reasons { - fn from(r: WithdrawReasons) -> Reasons { - if r == WithdrawReasons::TRANSACTION_PAYMENT { - Reasons::Fee - } else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) { - Reasons::All - } else { - Reasons::Misc - } - } + fn from(r: WithdrawReasons) -> Reasons { + if r == WithdrawReasons::TRANSACTION_PAYMENT { + Reasons::Fee + } else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) { + Reasons::All + } else { + Reasons::Misc + } + } } impl BitOr for Reasons { - type Output = Reasons; - fn bitor(self, other: Reasons) -> Reasons { - if self == other { - return self - } - Reasons::All - } + type Output = Reasons; + fn bitor(self, other: Reasons) -> Reasons { + if self == other { + return self; + } + Reasons::All + } } /// A single lock on a balance. There can be many of these on an account and they "overlap", so the /// same balance is frozen by multiple locks. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct BalanceLock { - /// An identifier for this lock. Only one lock may be in existence for each identifier. - pub id: LockIdentifier, - /// The amount which the free balance may not drop below when this lock is in effect. - pub amount: Balance, - /// If true, then the lock remains in effect even for payment of transaction fees. - pub reasons: Reasons, + /// An identifier for this lock. Only one lock may be in existence for each identifier. + pub id: LockIdentifier, + /// The amount which the free balance may not drop below when this lock is in effect. + pub amount: Balance, + /// If true, then the lock remains in effect even for payment of transaction fees. + pub reasons: Reasons, } /// Store named reserved balance. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct ReserveData { - /// The identifier for the named reserve. - pub id: ReserveIdentifier, - /// The amount of the named reserve. - pub amount: Balance, + /// The identifier for the named reserve. + pub id: ReserveIdentifier, + /// The amount of the named reserve. + pub amount: Balance, } /// All balance information for an account. #[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct AccountData { - /// Non-reserved part of the balance. There may still be restrictions on this, but it is the - /// total pool what may in principle be transferred, reserved and used for tipping. - /// - /// This is the only balance that matters in terms of most operations on tokens. It - /// alone is used to determine the balance when in the contract execution environment. - pub free: Balance, - /// Balance which is reserved and may not be used at all. - /// - /// This can still get slashed, but gets slashed last of all. - /// - /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens - /// that are still 'owned' by the account holder, but which are suspendable. - /// This includes named reserve and unnamed reserve. - pub reserved: Balance, - /// The amount that `free` may not drop below when withdrawing for *anything except transaction - /// fee payment*. - pub misc_frozen: Balance, - /// The amount that `free` may not drop below when withdrawing specifically for transaction - /// fee payment. - pub fee_frozen: Balance, + /// Non-reserved part of the balance. There may still be restrictions on this, but it is the + /// total pool what may in principle be transferred, reserved and used for tipping. + /// + /// This is the only balance that matters in terms of most operations on tokens. It + /// alone is used to determine the balance when in the contract execution environment. + pub free: Balance, + /// Balance which is reserved and may not be used at all. + /// + /// This can still get slashed, but gets slashed last of all. + /// + /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens + /// that are still 'owned' by the account holder, but which are suspendable. + /// This includes named reserve and unnamed reserve. + pub reserved: Balance, + /// The amount that `free` may not drop below when withdrawing for *anything except transaction + /// fee payment*. + pub misc_frozen: Balance, + /// The amount that `free` may not drop below when withdrawing specifically for transaction + /// fee payment. + pub fee_frozen: Balance, } impl AccountData { - /// How much this account's balance can be reduced for the given `reasons`. - fn usable(&self, reasons: Reasons) -> Balance { - self.free.saturating_sub(self.frozen(reasons)) - } - /// The amount that this account's free balance may not be reduced beyond for the given - /// `reasons`. - fn frozen(&self, reasons: Reasons) -> Balance { - match reasons { - Reasons::All => self.misc_frozen.max(self.fee_frozen), - Reasons::Misc => self.misc_frozen, - Reasons::Fee => self.fee_frozen, - } - } - /// The total balance in this account including any that is reserved and ignoring any frozen. - fn total(&self) -> Balance { - self.free.saturating_add(self.reserved) - } + /// How much this account's balance can be reduced for the given `reasons`. + fn usable(&self, reasons: Reasons) -> Balance { + self.free.saturating_sub(self.frozen(reasons)) + } + /// The amount that this account's free balance may not be reduced beyond for the given + /// `reasons`. + fn frozen(&self, reasons: Reasons) -> Balance { + match reasons { + Reasons::All => self.misc_frozen.max(self.fee_frozen), + Reasons::Misc => self.misc_frozen, + Reasons::Fee => self.fee_frozen, + } + } + /// The total balance in this account including any that is reserved and ignoring any frozen. + fn total(&self) -> Balance { + self.free.saturating_add(self.reserved) + } } pub struct DustCleaner, I: 'static = ()>( - Option<(T::AccountId, NegativeImbalance)>, + Option<(T::AccountId, NegativeImbalance)>, ); impl, I: 'static> Drop for DustCleaner { - fn drop(&mut self) { - if let Some((who, dust)) = self.0.take() { - Pallet::::deposit_event(Event::DustLost { account: who, amount: dust.peek() }); - T::DustRemoval::on_unbalanced(dust); - } - } + fn drop(&mut self) { + if let Some((who, dust)) = self.0.take() { + Pallet::::deposit_event(Event::DustLost { + account: who, + amount: dust.peek(), + }); + T::DustRemoval::on_unbalanced(dust); + } + } } +const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day + impl, I: 'static> Pallet { - /// Get the free balance of an account. - pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { - Self::account(who.borrow()).free - } - - /// Get the balance of an account that can be used for transfers, reservations, or any other - /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. - pub fn usable_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { - Self::account(who.borrow()).usable(Reasons::Misc) - } - - /// Get the balance of an account that can be used for paying transaction fees (not tipping, - /// or any other kind of fees, though). Will be at most `free_balance`. - pub fn usable_balance_for_fees(who: impl sp_std::borrow::Borrow) -> T::Balance { - Self::account(who.borrow()).usable(Reasons::Fee) - } - - /// Get the reserved balance of an account. - pub fn reserved_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { - Self::account(who.borrow()).reserved - } - - /// Get both the free and reserved balances of an account. - fn account(who: &T::AccountId) -> AccountData { - T::AccountStore::get(who) - } - - /// Handles any steps needed after mutating an account. - /// - /// This includes DustRemoval unbalancing, in the case than the `new` account's total balance - /// is non-zero but below ED. - /// - /// Returns two values: - /// - `Some` containing the the `new` account, iff the account has sufficient balance. - /// - `Some` containing the dust to be dropped, iff some dust should be dropped. - fn post_mutation( - _who: &T::AccountId, - new: AccountData, - ) -> (Option>, Option>) { - let total = new.total(); - if total < T::ExistentialDeposit::get() { - if total.is_zero() { - (None, None) - } else { - (None, Some(NegativeImbalance::new(total))) - } - } else { - (Some(new), None) - } - } - - fn deposit_consequence( - _who: &T::AccountId, - amount: T::Balance, - account: &AccountData, - mint: bool, - ) -> DepositConsequence { - if amount.is_zero() { - return DepositConsequence::Success - } - - if mint && TotalIssuance::::get().checked_add(&amount).is_none() { - return DepositConsequence::Overflow - } - - let new_total_balance = match account.total().checked_add(&amount) { - Some(x) => x, - None => return DepositConsequence::Overflow, - }; - - if new_total_balance < T::ExistentialDeposit::get() { - return DepositConsequence::BelowMinimum - } - - // NOTE: We assume that we are a provider, so don't need to do any checks in the - // case of account creation. - - DepositConsequence::Success - } - - fn withdraw_consequence( - who: &T::AccountId, - amount: T::Balance, - account: &AccountData, - ) -> WithdrawConsequence { - if amount.is_zero() { - return WithdrawConsequence::Success - } - - if TotalIssuance::::get().checked_sub(&amount).is_none() { - return WithdrawConsequence::Underflow - } - - let new_total_balance = match account.total().checked_sub(&amount) { - Some(x) => x, - None => return WithdrawConsequence::NoFunds, - }; - - // Provider restriction - total account balance cannot be reduced to zero if it cannot - // sustain the loss of a provider reference. - // NOTE: This assumes that the pallet is a provider (which is true). Is this ever changes, - // then this will need to adapt accordingly. - let ed = T::ExistentialDeposit::get(); - let success = if new_total_balance < ed { - if frame_system::Pallet::::can_dec_provider(who) { - WithdrawConsequence::ReducedToZero(new_total_balance) - } else { - return WithdrawConsequence::WouldDie - } - } else { - WithdrawConsequence::Success - }; - - // Enough free funds to have them be reduced. - let new_free_balance = match account.free.checked_sub(&amount) { - Some(b) => b, - None => return WithdrawConsequence::NoFunds, - }; - - // Eventual free funds must be no less than the frozen balance. - let min_balance = account.frozen(Reasons::All); - if new_free_balance < min_balance { - return WithdrawConsequence::Frozen - } - - success - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - pub fn mutate_account( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData) -> R, - ) -> Result { - Self::try_mutate_account(who, |a, _| -> Result { Ok(f(a)) }) - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the - /// result of `f` is an `Err`. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - fn try_mutate_account>( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData, bool) -> Result, - ) -> Result { - Self::try_mutate_account_with_dust(who, f).map(|(result, dust_cleaner)| { - drop(dust_cleaner); - result - }) - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the - /// result of `f` is an `Err`. - /// - /// It returns both the result from the closure, and an optional `DustCleaner` instance which - /// should be dropped once it is known that all nested mutates that could affect storage items - /// what the dust handler touches have completed. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - fn try_mutate_account_with_dust>( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData, bool) -> Result, - ) -> Result<(R, DustCleaner), E> { - let result = T::AccountStore::try_mutate_exists(who, |maybe_account| { - let is_new = maybe_account.is_none(); - let mut account = maybe_account.take().unwrap_or_default(); - f(&mut account, is_new).map(move |result| { - let maybe_endowed = if is_new { Some(account.free) } else { None }; - let maybe_account_maybe_dust = Self::post_mutation(who, account); - *maybe_account = maybe_account_maybe_dust.0; - (maybe_endowed, maybe_account_maybe_dust.1, result) - }) - }); - result.map(|(maybe_endowed, maybe_dust, result)| { - if let Some(endowed) = maybe_endowed { - Self::deposit_event(Event::Endowed { account: who.clone(), free_balance: endowed }); - } - let dust_cleaner = DustCleaner(maybe_dust.map(|dust| (who.clone(), dust))); - (result, dust_cleaner) - }) - } - - /// Update the account entry for `who`, given the locks. - fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { - let bounded_locks = WeakBoundedVec::<_, T::MaxLocks>::force_from( - locks.to_vec(), - Some("Balances Update Locks"), - ); - - if locks.len() as u32 > T::MaxLocks::get() { - log::warn!( - target: LOG_TARGET, - "Warning: A user has more currency locks than expected. \ + fn ensure_xcm_transfer_limit_not_exceeded( + account_id: &T::AccountId, + amount: T::Balance, + ) -> DispatchResult { + // check if account_id is in barrier list + + if let Some(transfer_limit) = >::get() { + let now = T::UnixTime::now().as_secs(); + let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; + let (mut transferred, last_transfer) = >::get(account_id) + .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + + if last_transfer < current_period { + transferred = Default::default(); + >::insert(account_id, (transferred, now)); + }; + + ensure!( + transferred + amount <= transfer_limit, + Error::::XcmTransfersLimitExceeded + ); + + Self::update_xcm_native_transfers(account_id, amount) + } + + Ok(()) + } + + fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { + if >::get().is_some() { + >::mutate_exists(account_id, |maybe_transfer| { + match maybe_transfer { + Some((current_amount, last_transfer)) => { + *current_amount = *current_amount + amount; + *last_transfer = T::UnixTime::now().as_secs(); + } + None => {} + } + }); + } + } + + /// Get the free balance of an account. + pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).free + } + + /// Get the balance of an account that can be used for transfers, reservations, or any other + /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. + pub fn usable_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).usable(Reasons::Misc) + } + + /// Get the balance of an account that can be used for paying transaction fees (not tipping, + /// or any other kind of fees, though). Will be at most `free_balance`. + pub fn usable_balance_for_fees(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).usable(Reasons::Fee) + } + + /// Get the reserved balance of an account. + pub fn reserved_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).reserved + } + + /// Get both the free and reserved balances of an account. + fn account(who: &T::AccountId) -> AccountData { + T::AccountStore::get(who) + } + + /// Handles any steps needed after mutating an account. + /// + /// This includes DustRemoval unbalancing, in the case than the `new` account's total balance + /// is non-zero but below ED. + /// + /// Returns two values: + /// - `Some` containing the the `new` account, iff the account has sufficient balance. + /// - `Some` containing the dust to be dropped, iff some dust should be dropped. + fn post_mutation( + _who: &T::AccountId, + new: AccountData, + ) -> ( + Option>, + Option>, + ) { + let total = new.total(); + if total < T::ExistentialDeposit::get() { + if total.is_zero() { + (None, None) + } else { + (None, Some(NegativeImbalance::new(total))) + } + } else { + (Some(new), None) + } + } + + fn deposit_consequence( + _who: &T::AccountId, + amount: T::Balance, + account: &AccountData, + mint: bool, + ) -> DepositConsequence { + if amount.is_zero() { + return DepositConsequence::Success; + } + + if mint && TotalIssuance::::get().checked_add(&amount).is_none() { + return DepositConsequence::Overflow; + } + + let new_total_balance = match account.total().checked_add(&amount) { + Some(x) => x, + None => return DepositConsequence::Overflow, + }; + + if new_total_balance < T::ExistentialDeposit::get() { + return DepositConsequence::BelowMinimum; + } + + // NOTE: We assume that we are a provider, so don't need to do any checks in the + // case of account creation. + + DepositConsequence::Success + } + + fn withdraw_consequence( + who: &T::AccountId, + amount: T::Balance, + account: &AccountData, + ) -> WithdrawConsequence { + if amount.is_zero() { + return WithdrawConsequence::Success; + } + + if TotalIssuance::::get().checked_sub(&amount).is_none() { + return WithdrawConsequence::Underflow; + } + + let new_total_balance = match account.total().checked_sub(&amount) { + Some(x) => x, + None => return WithdrawConsequence::NoFunds, + }; + + // Provider restriction - total account balance cannot be reduced to zero if it cannot + // sustain the loss of a provider reference. + // NOTE: This assumes that the pallet is a provider (which is true). Is this ever changes, + // then this will need to adapt accordingly. + let ed = T::ExistentialDeposit::get(); + let success = if new_total_balance < ed { + if frame_system::Pallet::::can_dec_provider(who) { + WithdrawConsequence::ReducedToZero(new_total_balance) + } else { + return WithdrawConsequence::WouldDie; + } + } else { + WithdrawConsequence::Success + }; + + // Enough free funds to have them be reduced. + let new_free_balance = match account.free.checked_sub(&amount) { + Some(b) => b, + None => return WithdrawConsequence::NoFunds, + }; + + // Eventual free funds must be no less than the frozen balance. + let min_balance = account.frozen(Reasons::All); + if new_free_balance < min_balance { + return WithdrawConsequence::Frozen; + } + + success + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + pub fn mutate_account( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData) -> R, + ) -> Result { + Self::try_mutate_account(who, |a, _| -> Result { Ok(f(a)) }) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the + /// result of `f` is an `Err`. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + fn try_mutate_account>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result { + Self::try_mutate_account_with_dust(who, f).map(|(result, dust_cleaner)| { + drop(dust_cleaner); + result + }) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the + /// result of `f` is an `Err`. + /// + /// It returns both the result from the closure, and an optional `DustCleaner` instance which + /// should be dropped once it is known that all nested mutates that could affect storage items + /// what the dust handler touches have completed. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + fn try_mutate_account_with_dust>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result<(R, DustCleaner), E> { + let result = T::AccountStore::try_mutate_exists(who, |maybe_account| { + let is_new = maybe_account.is_none(); + let mut account = maybe_account.take().unwrap_or_default(); + f(&mut account, is_new).map(move |result| { + let maybe_endowed = if is_new { Some(account.free) } else { None }; + let maybe_account_maybe_dust = Self::post_mutation(who, account); + *maybe_account = maybe_account_maybe_dust.0; + (maybe_endowed, maybe_account_maybe_dust.1, result) + }) + }); + result.map(|(maybe_endowed, maybe_dust, result)| { + if let Some(endowed) = maybe_endowed { + Self::deposit_event(Event::Endowed { + account: who.clone(), + free_balance: endowed, + }); + } + let dust_cleaner = DustCleaner(maybe_dust.map(|dust| (who.clone(), dust))); + (result, dust_cleaner) + }) + } + + /// Update the account entry for `who`, given the locks. + fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { + let bounded_locks = WeakBoundedVec::<_, T::MaxLocks>::force_from( + locks.to_vec(), + Some("Balances Update Locks"), + ); + + if locks.len() as u32 > T::MaxLocks::get() { + log::warn!( + target: LOG_TARGET, + "Warning: A user has more currency locks than expected. \ A runtime configuration adjustment may be needed." - ); - } - // No way this can fail since we do not alter the existential balances. - let res = Self::mutate_account(who, |b| { - b.misc_frozen = Zero::zero(); - b.fee_frozen = Zero::zero(); - for l in locks.iter() { - if l.reasons == Reasons::All || l.reasons == Reasons::Misc { - b.misc_frozen = b.misc_frozen.max(l.amount); - } - if l.reasons == Reasons::All || l.reasons == Reasons::Fee { - b.fee_frozen = b.fee_frozen.max(l.amount); - } - } - }); - debug_assert!(res.is_ok()); - - let existed = Locks::::contains_key(who); - if locks.is_empty() { - Locks::::remove(who); - if existed { - // TODO: use Locks::::hashed_key - // https://github.com/paritytech/substrate/issues/4969 - system::Pallet::::dec_consumers(who); - } - } else { - Locks::::insert(who, bounded_locks); - if !existed && system::Pallet::::inc_consumers_without_limit(who).is_err() { - // No providers for the locks. This is impossible under normal circumstances - // since the funds that are under the lock will themselves be stored in the - // account and therefore will need a reference. - log::warn!( - target: LOG_TARGET, - "Warning: Attempt to introduce lock consumer reference, yet no providers. \ + ); + } + // No way this can fail since we do not alter the existential balances. + let res = Self::mutate_account(who, |b| { + b.misc_frozen = Zero::zero(); + b.fee_frozen = Zero::zero(); + for l in locks.iter() { + if l.reasons == Reasons::All || l.reasons == Reasons::Misc { + b.misc_frozen = b.misc_frozen.max(l.amount); + } + if l.reasons == Reasons::All || l.reasons == Reasons::Fee { + b.fee_frozen = b.fee_frozen.max(l.amount); + } + } + }); + debug_assert!(res.is_ok()); + + let existed = Locks::::contains_key(who); + if locks.is_empty() { + Locks::::remove(who); + if existed { + // TODO: use Locks::::hashed_key + // https://github.com/paritytech/substrate/issues/4969 + system::Pallet::::dec_consumers(who); + } + } else { + Locks::::insert(who, bounded_locks); + if !existed && system::Pallet::::inc_consumers_without_limit(who).is_err() { + // No providers for the locks. This is impossible under normal circumstances + // since the funds that are under the lock will themselves be stored in the + // account and therefore will need a reference. + log::warn!( + target: LOG_TARGET, + "Warning: Attempt to introduce lock consumer reference, yet no providers. \ This is unexpected but should be safe." - ); - } - } - } - - /// Move the reserved balance of one account into the balance of another, according to `status`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. - /// - /// NOTE: returns actual amount of transferred value in `Ok` case. - fn do_transfer_reserved( - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: T::Balance, - best_effort: bool, - status: Status, - ) -> Result { - if value.is_zero() { - return Ok(Zero::zero()) - } - - if slashed == beneficiary { - return match status { - Status::Free => Ok(value.saturating_sub(Self::unreserve(slashed, value))), - Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance(slashed))), - } - } - - let ((actual, _maybe_one_dust), _maybe_other_dust) = Self::try_mutate_account_with_dust( - beneficiary, - |to_account, is_new| -> Result<(T::Balance, DustCleaner), DispatchError> { - ensure!(!is_new, Error::::DeadAccount); - Self::try_mutate_account_with_dust( - slashed, - |from_account, _| -> Result { - let actual = cmp::min(from_account.reserved, value); - ensure!(best_effort || actual == value, Error::::InsufficientBalance); - match status { - Status::Free => - to_account.free = to_account - .free - .checked_add(&actual) - .ok_or(ArithmeticError::Overflow)?, - Status::Reserved => - to_account.reserved = to_account - .reserved - .checked_add(&actual) - .ok_or(ArithmeticError::Overflow)?, - } - from_account.reserved -= actual; - Ok(actual) - }, - ) - }, - )?; - - Self::deposit_event(Event::ReserveRepatriated { - from: slashed.clone(), - to: beneficiary.clone(), - amount: actual, - destination_status: status, - }); - Ok(actual) - } + ); + } + } + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + /// + /// NOTE: returns actual amount of transferred value in `Ok` case. + fn do_transfer_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: T::Balance, + best_effort: bool, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()); + } + + if slashed == beneficiary { + return match status { + Status::Free => Ok(value.saturating_sub(Self::unreserve(slashed, value))), + Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance(slashed))), + }; + } + + let ((actual, _maybe_one_dust), _maybe_other_dust) = Self::try_mutate_account_with_dust( + beneficiary, + |to_account, is_new| -> Result<(T::Balance, DustCleaner), DispatchError> { + ensure!(!is_new, Error::::DeadAccount); + Self::try_mutate_account_with_dust( + slashed, + |from_account, _| -> Result { + let actual = cmp::min(from_account.reserved, value); + ensure!( + best_effort || actual == value, + Error::::InsufficientBalance + ); + match status { + Status::Free => { + to_account.free = to_account + .free + .checked_add(&actual) + .ok_or(ArithmeticError::Overflow)? + } + Status::Reserved => { + to_account.reserved = to_account + .reserved + .checked_add(&actual) + .ok_or(ArithmeticError::Overflow)? + } + } + from_account.reserved -= actual; + Ok(actual) + }, + ) + }, + )?; + + Self::deposit_event(Event::ReserveRepatriated { + from: slashed.clone(), + to: beneficiary.clone(), + amount: actual, + destination_status: status, + }); + Ok(actual) + } } impl, I: 'static> fungible::Inspect for Pallet { - type Balance = T::Balance; - - fn total_issuance() -> Self::Balance { - TotalIssuance::::get() - } - fn active_issuance() -> Self::Balance { - TotalIssuance::::get().saturating_sub(InactiveIssuance::::get()) - } - fn minimum_balance() -> Self::Balance { - T::ExistentialDeposit::get() - } - fn balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).total() - } - fn reducible_balance(who: &T::AccountId, keep_alive: bool) -> Self::Balance { - let a = Self::account(who); - // Liquid balance is what is neither reserved nor locked/frozen. - let liquid = a.free.saturating_sub(a.fee_frozen.max(a.misc_frozen)); - if frame_system::Pallet::::can_dec_provider(who) && !keep_alive { - liquid - } else { - // `must_remain_to_exist` is the part of liquid balance which must remain to keep total - // over ED. - let must_remain_to_exist = - T::ExistentialDeposit::get().saturating_sub(a.total() - liquid); - liquid.saturating_sub(must_remain_to_exist) - } - } - fn can_deposit(who: &T::AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence { - Self::deposit_consequence(who, amount, &Self::account(who), mint) - } - fn can_withdraw( - who: &T::AccountId, - amount: Self::Balance, - ) -> WithdrawConsequence { - Self::withdraw_consequence(who, amount, &Self::account(who)) - } + type Balance = T::Balance; + + fn total_issuance() -> Self::Balance { + TotalIssuance::::get() + } + fn active_issuance() -> Self::Balance { + TotalIssuance::::get().saturating_sub(InactiveIssuance::::get()) + } + fn minimum_balance() -> Self::Balance { + T::ExistentialDeposit::get() + } + fn balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).total() + } + fn reducible_balance(who: &T::AccountId, keep_alive: bool) -> Self::Balance { + let a = Self::account(who); + // Liquid balance is what is neither reserved nor locked/frozen. + let liquid = a.free.saturating_sub(a.fee_frozen.max(a.misc_frozen)); + if frame_system::Pallet::::can_dec_provider(who) && !keep_alive { + liquid + } else { + // `must_remain_to_exist` is the part of liquid balance which must remain to keep total + // over ED. + let must_remain_to_exist = + T::ExistentialDeposit::get().saturating_sub(a.total() - liquid); + liquid.saturating_sub(must_remain_to_exist) + } + } + fn can_deposit(who: &T::AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence { + Self::deposit_consequence(who, amount, &Self::account(who), mint) + } + fn can_withdraw( + who: &T::AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + Self::withdraw_consequence(who, amount, &Self::account(who)) + } } impl, I: 'static> fungible::Mutate for Pallet { - fn mint_into(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - if amount.is_zero() { - return Ok(()) - } - Self::try_mutate_account(who, |account, _is_new| -> DispatchResult { - Self::deposit_consequence(who, amount, account, true).into_result()?; - account.free += amount; - Ok(()) - })?; - TotalIssuance::::mutate(|t| *t += amount); - Self::deposit_event(Event::Deposit { who: who.clone(), amount }); - Ok(()) - } - - fn burn_from( - who: &T::AccountId, - amount: Self::Balance, - ) -> Result { - if amount.is_zero() { - return Ok(Self::Balance::zero()) - } - let actual = Self::try_mutate_account( - who, - |account, _is_new| -> Result { - let extra = Self::withdraw_consequence(who, amount, account).into_result()?; - let actual = amount + extra; - account.free -= actual; - Ok(actual) - }, - )?; - TotalIssuance::::mutate(|t| *t -= actual); - Self::deposit_event(Event::Withdraw { who: who.clone(), amount }); - Ok(actual) - } + fn mint_into(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + Self::try_mutate_account(who, |account, _is_new| -> DispatchResult { + Self::deposit_consequence(who, amount, account, true).into_result()?; + account.free += amount; + Ok(()) + })?; + TotalIssuance::::mutate(|t| *t += amount); + Self::deposit_event(Event::Deposit { + who: who.clone(), + amount, + }); + Ok(()) + } + + fn burn_from( + who: &T::AccountId, + amount: Self::Balance, + ) -> Result { + if amount.is_zero() { + return Ok(Self::Balance::zero()); + } + let actual = Self::try_mutate_account( + who, + |account, _is_new| -> Result { + let extra = Self::withdraw_consequence(who, amount, account).into_result()?; + let actual = amount + extra; + account.free -= actual; + Ok(actual) + }, + )?; + TotalIssuance::::mutate(|t| *t -= actual); + Self::deposit_event(Event::Withdraw { + who: who.clone(), + amount, + }); + Ok(actual) + } } impl, I: 'static> fungible::Transfer for Pallet { - fn transfer( - source: &T::AccountId, - dest: &T::AccountId, - amount: T::Balance, - keep_alive: bool, - ) -> Result { - let er = if keep_alive { KeepAlive } else { AllowDeath }; - >::transfer(source, dest, amount, er).map(|_| amount) - } - - fn deactivate(amount: Self::Balance) { - InactiveIssuance::::mutate(|b| b.saturating_accrue(amount)); - } - - fn reactivate(amount: Self::Balance) { - InactiveIssuance::::mutate(|b| b.saturating_reduce(amount)); - } + fn transfer( + source: &T::AccountId, + dest: &T::AccountId, + amount: T::Balance, + keep_alive: bool, + ) -> Result { + let er = if keep_alive { KeepAlive } else { AllowDeath }; + >::transfer(source, dest, amount, er).map(|_| amount) + } + + fn deactivate(amount: Self::Balance) { + InactiveIssuance::::mutate(|b| b.saturating_accrue(amount)); + } + + fn reactivate(amount: Self::Balance) { + InactiveIssuance::::mutate(|b| b.saturating_reduce(amount)); + } } impl, I: 'static> fungible::Unbalanced for Pallet { - fn set_balance(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - Self::mutate_account(who, |account| -> DispatchResult { - // fungibles::Unbalanced::decrease_balance didn't check account.reserved - // free = new_balance - reserved - account.free = - amount.checked_sub(&account.reserved).ok_or(ArithmeticError::Underflow)?; - Self::deposit_event(Event::BalanceSet { - who: who.clone(), - free: account.free, - reserved: account.reserved, - }); - - Ok(()) - })? - } - - fn set_total_issuance(amount: Self::Balance) { - TotalIssuance::::mutate(|t| *t = amount); - } + fn set_balance(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + Self::mutate_account(who, |account| -> DispatchResult { + // fungibles::Unbalanced::decrease_balance didn't check account.reserved + // free = new_balance - reserved + account.free = amount + .checked_sub(&account.reserved) + .ok_or(ArithmeticError::Underflow)?; + Self::deposit_event(Event::BalanceSet { + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + + Ok(()) + })? + } + + fn set_total_issuance(amount: Self::Balance) { + TotalIssuance::::mutate(|t| *t = amount); + } } impl, I: 'static> fungible::InspectHold for Pallet { - fn balance_on_hold(who: &T::AccountId) -> T::Balance { - Self::account(who).reserved - } - fn can_hold(who: &T::AccountId, amount: T::Balance) -> bool { - let a = Self::account(who); - let min_balance = T::ExistentialDeposit::get().max(a.frozen(Reasons::All)); - if a.reserved.checked_add(&amount).is_none() { - return false - } - // We require it to be min_balance + amount to ensure that the full reserved funds may be - // slashed without compromising locked funds or destroying the account. - let required_free = match min_balance.checked_add(&amount) { - Some(x) => x, - None => return false, - }; - a.free >= required_free - } + fn balance_on_hold(who: &T::AccountId) -> T::Balance { + Self::account(who).reserved + } + fn can_hold(who: &T::AccountId, amount: T::Balance) -> bool { + let a = Self::account(who); + let min_balance = T::ExistentialDeposit::get().max(a.frozen(Reasons::All)); + if a.reserved.checked_add(&amount).is_none() { + return false; + } + // We require it to be min_balance + amount to ensure that the full reserved funds may be + // slashed without compromising locked funds or destroying the account. + let required_free = match min_balance.checked_add(&amount) { + Some(x) => x, + None => return false, + }; + a.free >= required_free + } } impl, I: 'static> fungible::MutateHold for Pallet { - fn hold(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - if amount.is_zero() { - return Ok(()) - } - ensure!(Self::can_reserve(who, amount), Error::::InsufficientBalance); - Self::mutate_account(who, |a| { - a.free -= amount; - a.reserved += amount; - })?; - Ok(()) - } - fn release( - who: &T::AccountId, - amount: Self::Balance, - best_effort: bool, - ) -> Result { - if amount.is_zero() { - return Ok(amount) - } - // Done on a best-effort basis. - Self::try_mutate_account(who, |a, _| { - let new_free = a.free.saturating_add(amount.min(a.reserved)); - let actual = new_free - a.free; - ensure!(best_effort || actual == amount, Error::::InsufficientBalance); - // ^^^ Guaranteed to be <= amount and <= a.reserved - a.free = new_free; - a.reserved = a.reserved.saturating_sub(actual); - Ok(actual) - }) - } - fn transfer_held( - source: &T::AccountId, - dest: &T::AccountId, - amount: Self::Balance, - best_effort: bool, - on_hold: bool, - ) -> Result { - let status = if on_hold { Status::Reserved } else { Status::Free }; - Self::do_transfer_reserved(source, dest, amount, best_effort, status) - } + fn hold(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + ensure!( + Self::can_reserve(who, amount), + Error::::InsufficientBalance + ); + Self::mutate_account(who, |a| { + a.free -= amount; + a.reserved += amount; + })?; + Ok(()) + } + fn release( + who: &T::AccountId, + amount: Self::Balance, + best_effort: bool, + ) -> Result { + if amount.is_zero() { + return Ok(amount); + } + // Done on a best-effort basis. + Self::try_mutate_account(who, |a, _| { + let new_free = a.free.saturating_add(amount.min(a.reserved)); + let actual = new_free - a.free; + ensure!( + best_effort || actual == amount, + Error::::InsufficientBalance + ); + // ^^^ Guaranteed to be <= amount and <= a.reserved + a.free = new_free; + a.reserved = a.reserved.saturating_sub(actual); + Ok(actual) + }) + } + fn transfer_held( + source: &T::AccountId, + dest: &T::AccountId, + amount: Self::Balance, + best_effort: bool, + on_hold: bool, + ) -> Result { + let status = if on_hold { + Status::Reserved + } else { + Status::Free + }; + Self::do_transfer_reserved(source, dest, amount, best_effort, status) + } } // wrapping these imbalances in a private module is necessary to ensure absolute privacy // of the inner member. mod imbalances { - use super::{result, Config, Imbalance, RuntimeDebug, Saturating, TryDrop, Zero}; - use frame_support::traits::SameOrOther; - use sp_std::mem; - - /// Opaque, move-only struct with private fields that serves as a token denoting that - /// funds have been created without any equal and opposite accounting. - #[must_use] - #[derive(RuntimeDebug, PartialEq, Eq)] - pub struct PositiveImbalance, I: 'static = ()>(T::Balance); - - impl, I: 'static> PositiveImbalance { - /// Create a new positive imbalance from a balance. - pub fn new(amount: T::Balance) -> Self { - PositiveImbalance(amount) - } - } - - /// Opaque, move-only struct with private fields that serves as a token denoting that - /// funds have been destroyed without any equal and opposite accounting. - #[must_use] - #[derive(RuntimeDebug, PartialEq, Eq)] - pub struct NegativeImbalance, I: 'static = ()>(T::Balance); - - impl, I: 'static> NegativeImbalance { - /// Create a new negative imbalance from a balance. - pub fn new(amount: T::Balance) -> Self { - NegativeImbalance(amount) - } - } - - impl, I: 'static> TryDrop for PositiveImbalance { - fn try_drop(self) -> result::Result<(), Self> { - self.drop_zero() - } - } - - impl, I: 'static> Default for PositiveImbalance { - fn default() -> Self { - Self::zero() - } - } - - impl, I: 'static> Imbalance for PositiveImbalance { - type Opposite = NegativeImbalance; - - fn zero() -> Self { - Self(Zero::zero()) - } - fn drop_zero(self) -> result::Result<(), Self> { - if self.0.is_zero() { - Ok(()) - } else { - Err(self) - } - } - fn split(self, amount: T::Balance) -> (Self, Self) { - let first = self.0.min(amount); - let second = self.0 - first; - - mem::forget(self); - (Self(first), Self(second)) - } - fn merge(mut self, other: Self) -> Self { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - - self - } - fn subsume(&mut self, other: Self) { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - } - fn offset(self, other: Self::Opposite) -> SameOrOther { - let (a, b) = (self.0, other.0); - mem::forget((self, other)); - - if a > b { - SameOrOther::Same(Self(a - b)) - } else if b > a { - SameOrOther::Other(NegativeImbalance::new(b - a)) - } else { - SameOrOther::None - } - } - fn peek(&self) -> T::Balance { - self.0 - } - } - - impl, I: 'static> TryDrop for NegativeImbalance { - fn try_drop(self) -> result::Result<(), Self> { - self.drop_zero() - } - } - - impl, I: 'static> Default for NegativeImbalance { - fn default() -> Self { - Self::zero() - } - } - - impl, I: 'static> Imbalance for NegativeImbalance { - type Opposite = PositiveImbalance; - - fn zero() -> Self { - Self(Zero::zero()) - } - fn drop_zero(self) -> result::Result<(), Self> { - if self.0.is_zero() { - Ok(()) - } else { - Err(self) - } - } - fn split(self, amount: T::Balance) -> (Self, Self) { - let first = self.0.min(amount); - let second = self.0 - first; - - mem::forget(self); - (Self(first), Self(second)) - } - fn merge(mut self, other: Self) -> Self { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - - self - } - fn subsume(&mut self, other: Self) { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - } - fn offset(self, other: Self::Opposite) -> SameOrOther { - let (a, b) = (self.0, other.0); - mem::forget((self, other)); - - if a > b { - SameOrOther::Same(Self(a - b)) - } else if b > a { - SameOrOther::Other(PositiveImbalance::new(b - a)) - } else { - SameOrOther::None - } - } - fn peek(&self) -> T::Balance { - self.0 - } - } - - impl, I: 'static> Drop for PositiveImbalance { - /// Basic drop handler will just square up the total issuance. - fn drop(&mut self) { - >::mutate(|v| *v = v.saturating_add(self.0)); - } - } - - impl, I: 'static> Drop for NegativeImbalance { - /// Basic drop handler will just square up the total issuance. - fn drop(&mut self) { - >::mutate(|v| *v = v.saturating_sub(self.0)); - } - } + use super::{result, Config, Imbalance, RuntimeDebug, Saturating, TryDrop, Zero}; + use frame_support::traits::SameOrOther; + use sp_std::mem; + + /// Opaque, move-only struct with private fields that serves as a token denoting that + /// funds have been created without any equal and opposite accounting. + #[must_use] + #[derive(RuntimeDebug, PartialEq, Eq)] + pub struct PositiveImbalance, I: 'static = ()>(T::Balance); + + impl, I: 'static> PositiveImbalance { + /// Create a new positive imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + PositiveImbalance(amount) + } + } + + /// Opaque, move-only struct with private fields that serves as a token denoting that + /// funds have been destroyed without any equal and opposite accounting. + #[must_use] + #[derive(RuntimeDebug, PartialEq, Eq)] + pub struct NegativeImbalance, I: 'static = ()>(T::Balance); + + impl, I: 'static> NegativeImbalance { + /// Create a new negative imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + NegativeImbalance(amount) + } + } + + impl, I: 'static> TryDrop for PositiveImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } + } + + impl, I: 'static> Default for PositiveImbalance { + fn default() -> Self { + Self::zero() + } + } + + impl, I: 'static> Imbalance for PositiveImbalance { + type Opposite = NegativeImbalance; + + fn zero() -> Self { + Self(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0 - first; + + mem::forget(self); + (Self(first), Self(second)) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self(a - b)) + } else if b > a { + SameOrOther::Other(NegativeImbalance::new(b - a)) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + } + + impl, I: 'static> TryDrop for NegativeImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } + } + + impl, I: 'static> Default for NegativeImbalance { + fn default() -> Self { + Self::zero() + } + } + + impl, I: 'static> Imbalance for NegativeImbalance { + type Opposite = PositiveImbalance; + + fn zero() -> Self { + Self(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0 - first; + + mem::forget(self); + (Self(first), Self(second)) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self(a - b)) + } else if b > a { + SameOrOther::Other(PositiveImbalance::new(b - a)) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + } + + impl, I: 'static> Drop for PositiveImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + >::mutate(|v| *v = v.saturating_add(self.0)); + } + } + + impl, I: 'static> Drop for NegativeImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + >::mutate(|v| *v = v.saturating_sub(self.0)); + } + } } impl, I: 'static> Currency for Pallet where - T::Balance: MaybeSerializeDeserialize + Debug, + T::Balance: MaybeSerializeDeserialize + Debug, { - type Balance = T::Balance; - type PositiveImbalance = PositiveImbalance; - type NegativeImbalance = NegativeImbalance; - - fn total_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).total() - } - - // Check if `value` amount of free balance can be slashed from `who`. - fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { - if value.is_zero() { - return true - } - Self::free_balance(who) >= value - } - - fn total_issuance() -> Self::Balance { - TotalIssuance::::get() - } - - fn active_issuance() -> Self::Balance { - >::active_issuance() - } - - fn deactivate(amount: Self::Balance) { - >::deactivate(amount); - } - - fn reactivate(amount: Self::Balance) { - >::reactivate(amount); - } - - fn minimum_balance() -> Self::Balance { - T::ExistentialDeposit::get() - } - - // Burn funds from the total issuance, returning a positive imbalance for the amount burned. - // Is a no-op if amount to be burned is zero. - fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { - if amount.is_zero() { - return PositiveImbalance::zero() - } - >::mutate(|issued| { - *issued = issued.checked_sub(&amount).unwrap_or_else(|| { - amount = *issued; - Zero::zero() - }); - }); - PositiveImbalance::new(amount) - } - - // Create new funds into the total issuance, returning a negative imbalance - // for the amount issued. - // Is a no-op if amount to be issued it zero. - fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { - if amount.is_zero() { - return NegativeImbalance::zero() - } - >::mutate(|issued| { - *issued = issued.checked_add(&amount).unwrap_or_else(|| { - amount = Self::Balance::max_value() - *issued; - Self::Balance::max_value() - }) - }); - NegativeImbalance::new(amount) - } - - fn free_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).free - } - - // Ensure that an account can withdraw from their free balance given any existing withdrawal - // restrictions like locks and vesting balance. - // Is a no-op if amount to be withdrawn is zero. - // - // # - // Despite iterating over a list of locks, they are limited by the number of - // lock IDs, which means the number of runtime pallets that intend to use and create locks. - // # - fn ensure_can_withdraw( - who: &T::AccountId, - amount: T::Balance, - reasons: WithdrawReasons, - new_balance: T::Balance, - ) -> DispatchResult { - if amount.is_zero() { - return Ok(()) - } - let min_balance = Self::account(who).frozen(reasons.into()); - ensure!(new_balance >= min_balance, Error::::LiquidityRestrictions); - Ok(()) - } - - // Transfer some free balance from `transactor` to `dest`, respecting existence requirements. - // Is a no-op if value to be transferred is zero or the `transactor` is the same as `dest`. - fn transfer( - transactor: &T::AccountId, - dest: &T::AccountId, - value: Self::Balance, - existence_requirement: ExistenceRequirement, - ) -> DispatchResult { - if value.is_zero() || transactor == dest { - return Ok(()) - } - - Self::try_mutate_account_with_dust( - dest, - |to_account, _| -> Result, DispatchError> { - Self::try_mutate_account_with_dust( - transactor, - |from_account, _| -> DispatchResult { - from_account.free = from_account - .free - .checked_sub(&value) - .ok_or(Error::::InsufficientBalance)?; - - // NOTE: total stake being stored in the same type means that this could - // never overflow but better to be safe than sorry. - to_account.free = - to_account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?; - - let ed = T::ExistentialDeposit::get(); - ensure!(to_account.total() >= ed, Error::::ExistentialDeposit); - - Self::ensure_can_withdraw( - transactor, - value, - WithdrawReasons::TRANSFER, - from_account.free, - ) - .map_err(|_| Error::::LiquidityRestrictions)?; - - // TODO: This is over-conservative. There may now be other providers, and - // this pallet may not even be a provider. - let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; - let allow_death = - allow_death && system::Pallet::::can_dec_provider(transactor); - ensure!( - allow_death || from_account.total() >= ed, - Error::::KeepAlive - ); - - Ok(()) - }, - ) - .map(|(_, maybe_dust_cleaner)| maybe_dust_cleaner) - }, - )?; - - // Emit transfer event. - Self::deposit_event(Event::Transfer { - from: transactor.clone(), - to: dest.clone(), - amount: value, - }); - - Ok(()) - } - - /// Slash a target account `who`, returning the negative imbalance created and any left over - /// amount that could not be slashed. - /// - /// Is a no-op if `value` to be slashed is zero or the account does not exist. - /// - /// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn - /// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid - /// having to draw from reserved funds, however we err on the side of punishment if things are - /// inconsistent or `can_slash` wasn't used appropriately. - fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (NegativeImbalance::zero(), Zero::zero()) - } - if Self::total_balance(who).is_zero() { - return (NegativeImbalance::zero(), value) - } - - for attempt in 0..2 { - match Self::try_mutate_account( + type Balance = T::Balance; + type PositiveImbalance = PositiveImbalance; + type NegativeImbalance = NegativeImbalance; + + fn total_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).total() + } + + // Check if `value` amount of free balance can be slashed from `who`. + fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true; + } + Self::free_balance(who) >= value + } + + fn total_issuance() -> Self::Balance { + TotalIssuance::::get() + } + + fn active_issuance() -> Self::Balance { + >::active_issuance() + } + + fn deactivate(amount: Self::Balance) { + >::deactivate(amount); + } + + fn reactivate(amount: Self::Balance) { + >::reactivate(amount); + } + + fn minimum_balance() -> Self::Balance { + T::ExistentialDeposit::get() + } + + // Burn funds from the total issuance, returning a positive imbalance for the amount burned. + // Is a no-op if amount to be burned is zero. + fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { + if amount.is_zero() { + return PositiveImbalance::zero(); + } + >::mutate(|issued| { + *issued = issued.checked_sub(&amount).unwrap_or_else(|| { + amount = *issued; + Zero::zero() + }); + }); + PositiveImbalance::new(amount) + } + + // Create new funds into the total issuance, returning a negative imbalance + // for the amount issued. + // Is a no-op if amount to be issued it zero. + fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { + if amount.is_zero() { + return NegativeImbalance::zero(); + } + >::mutate(|issued| { + *issued = issued.checked_add(&amount).unwrap_or_else(|| { + amount = Self::Balance::max_value() - *issued; + Self::Balance::max_value() + }) + }); + NegativeImbalance::new(amount) + } + + fn free_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).free + } + + // Ensure that an account can withdraw from their free balance given any existing withdrawal + // restrictions like locks and vesting balance. + // Is a no-op if amount to be withdrawn is zero. + // + // # + // Despite iterating over a list of locks, they are limited by the number of + // lock IDs, which means the number of runtime pallets that intend to use and create locks. + // # + fn ensure_can_withdraw( + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + new_balance: T::Balance, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + let min_balance = Self::account(who).frozen(reasons.into()); + ensure!( + new_balance >= min_balance, + Error::::LiquidityRestrictions + ); + Ok(()) + } + + // Transfer some free balance from `transactor` to `dest`, respecting existence requirements. + // Is a no-op if value to be transferred is zero or the `transactor` is the same as `dest`. + fn transfer( + transactor: &T::AccountId, + dest: &T::AccountId, + value: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + if value.is_zero() || transactor == dest { + return Ok(()); + } + + Self::try_mutate_account_with_dust( + dest, + |to_account, _| -> Result, DispatchError> { + Self::try_mutate_account_with_dust( + transactor, + |from_account, _| -> DispatchResult { + from_account.free = from_account + .free + .checked_sub(&value) + .ok_or(Error::::InsufficientBalance)?; + + // NOTE: total stake being stored in the same type means that this could + // never overflow but better to be safe than sorry. + to_account.free = to_account + .free + .checked_add(&value) + .ok_or(ArithmeticError::Overflow)?; + + let ed = T::ExistentialDeposit::get(); + ensure!(to_account.total() >= ed, Error::::ExistentialDeposit); + + Self::ensure_can_withdraw( + transactor, + value, + WithdrawReasons::TRANSFER, + from_account.free, + ) + .map_err(|_| Error::::LiquidityRestrictions)?; + + // TODO: This is over-conservative. There may now be other providers, and + // this pallet may not even be a provider. + let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; + let allow_death = + allow_death && system::Pallet::::can_dec_provider(transactor); + ensure!( + allow_death || from_account.total() >= ed, + Error::::KeepAlive + ); + + Ok(()) + }, + ) + .map(|(_, maybe_dust_cleaner)| maybe_dust_cleaner) + }, + )?; + + // Emit transfer event. + Self::deposit_event(Event::Transfer { + from: transactor.clone(), + to: dest.clone(), + amount: value, + }); + + Ok(()) + } + + /// Slash a target account `who`, returning the negative imbalance created and any left over + /// amount that could not be slashed. + /// + /// Is a no-op if `value` to be slashed is zero or the account does not exist. + /// + /// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn + /// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid + /// having to draw from reserved funds, however we err on the side of punishment if things are + /// inconsistent or `can_slash` wasn't used appropriately. + fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()); + } + if Self::total_balance(who).is_zero() { + return (NegativeImbalance::zero(), value); + } + + for attempt in 0..2 { + match Self::try_mutate_account( who, |account, _is_new| @@ -1635,109 +1778,126 @@ where }, Err(_) => (), } - } - - // Should never get here. But we'll be defensive anyway. - (Self::NegativeImbalance::zero(), value) - } - - /// Deposit some `value` into the free balance of an existing target account `who`. - /// - /// Is a no-op if the `value` to be deposited is zero. - fn deposit_into_existing( - who: &T::AccountId, - value: Self::Balance, - ) -> Result { - if value.is_zero() { - return Ok(PositiveImbalance::zero()) - } - - Self::try_mutate_account( - who, - |account, is_new| -> Result { - ensure!(!is_new, Error::::DeadAccount); - account.free = account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?; - Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); - Ok(PositiveImbalance::new(value)) - }, - ) - } - - /// Deposit some `value` into the free balance of `who`, possibly creating a new account. - /// - /// This function is a no-op if: - /// - the `value` to be deposited is zero; or - /// - the `value` to be deposited is less than the required ED and the account does not yet - /// exist; or - /// - the deposit would necessitate the account to exist and there are no provider references; - /// or - /// - `value` is so large it would cause the balance of `who` to overflow. - fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { - if value.is_zero() { - return Self::PositiveImbalance::zero() - } - - Self::try_mutate_account( - who, - |account, is_new| -> Result { - let ed = T::ExistentialDeposit::get(); - ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); - - // defensive only: overflow should never happen, however in case it does, then this - // operation is a no-op. - account.free = match account.free.checked_add(&value) { - Some(x) => x, - None => return Ok(Self::PositiveImbalance::zero()), - }; - - Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); - Ok(PositiveImbalance::new(value)) - }, - ) - .unwrap_or_else(|_| Self::PositiveImbalance::zero()) - } - - /// Withdraw some free balance from an account, respecting existence requirements. - /// - /// Is a no-op if value to be withdrawn is zero. - fn withdraw( - who: &T::AccountId, - value: Self::Balance, - reasons: WithdrawReasons, - liveness: ExistenceRequirement, - ) -> result::Result { - if value.is_zero() { - return Ok(NegativeImbalance::zero()) - } - - Self::try_mutate_account( - who, - |account, _| -> Result { - let new_free_account = - account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; - - // bail if we need to keep the account alive and this would kill it. - let ed = T::ExistentialDeposit::get(); - let would_be_dead = new_free_account + account.reserved < ed; - let would_kill = would_be_dead && account.free + account.reserved >= ed; - ensure!(liveness == AllowDeath || !would_kill, Error::::KeepAlive); - - Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; - - account.free = new_free_account; - - Self::deposit_event(Event::Withdraw { who: who.clone(), amount: value }); - Ok(NegativeImbalance::new(value)) - }, - ) - } - - /// Force the new free balance of a target account `who` to some new value `balance`. - fn make_free_balance_be( - who: &T::AccountId, - value: Self::Balance, - ) -> SignedImbalance { - Self::try_mutate_account( + } + + // Should never get here. But we'll be defensive anyway. + (Self::NegativeImbalance::zero(), value) + } + + /// Deposit some `value` into the free balance of an existing target account `who`. + /// + /// Is a no-op if the `value` to be deposited is zero. + fn deposit_into_existing( + who: &T::AccountId, + value: Self::Balance, + ) -> Result { + if value.is_zero() { + return Ok(PositiveImbalance::zero()); + } + + Self::try_mutate_account( + who, + |account, is_new| -> Result { + ensure!(!is_new, Error::::DeadAccount); + account.free = account + .free + .checked_add(&value) + .ok_or(ArithmeticError::Overflow)?; + Self::deposit_event(Event::Deposit { + who: who.clone(), + amount: value, + }); + Ok(PositiveImbalance::new(value)) + }, + ) + } + + /// Deposit some `value` into the free balance of `who`, possibly creating a new account. + /// + /// This function is a no-op if: + /// - the `value` to be deposited is zero; or + /// - the `value` to be deposited is less than the required ED and the account does not yet + /// exist; or + /// - the deposit would necessitate the account to exist and there are no provider references; + /// or + /// - `value` is so large it would cause the balance of `who` to overflow. + fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { + if value.is_zero() { + return Self::PositiveImbalance::zero(); + } + + Self::try_mutate_account( + who, + |account, is_new| -> Result { + let ed = T::ExistentialDeposit::get(); + ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); + + // defensive only: overflow should never happen, however in case it does, then this + // operation is a no-op. + account.free = match account.free.checked_add(&value) { + Some(x) => x, + None => return Ok(Self::PositiveImbalance::zero()), + }; + + Self::deposit_event(Event::Deposit { + who: who.clone(), + amount: value, + }); + Ok(PositiveImbalance::new(value)) + }, + ) + .unwrap_or_else(|_| Self::PositiveImbalance::zero()) + } + + /// Withdraw some free balance from an account, respecting existence requirements. + /// + /// Is a no-op if value to be withdrawn is zero. + fn withdraw( + who: &T::AccountId, + value: Self::Balance, + reasons: WithdrawReasons, + liveness: ExistenceRequirement, + ) -> result::Result { + if value.is_zero() { + return Ok(NegativeImbalance::zero()); + } + + Self::try_mutate_account( + who, + |account, _| -> Result { + let new_free_account = account + .free + .checked_sub(&value) + .ok_or(Error::::InsufficientBalance)?; + + // bail if we need to keep the account alive and this would kill it. + let ed = T::ExistentialDeposit::get(); + let would_be_dead = new_free_account + account.reserved < ed; + let would_kill = would_be_dead && account.free + account.reserved >= ed; + ensure!( + liveness == AllowDeath || !would_kill, + Error::::KeepAlive + ); + + Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; + + account.free = new_free_account; + + Self::deposit_event(Event::Withdraw { + who: who.clone(), + amount: value, + }); + Ok(NegativeImbalance::new(value)) + }, + ) + } + + /// Force the new free balance of a target account `who` to some new value `balance`. + fn make_free_balance_be( + who: &T::AccountId, + value: Self::Balance, + ) -> SignedImbalance { + Self::try_mutate_account( who, |account, is_new| @@ -1768,312 +1928,340 @@ where }, ) .unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) - } + } } impl, I: 'static> ReservableCurrency for Pallet where - T::Balance: MaybeSerializeDeserialize + Debug, + T::Balance: MaybeSerializeDeserialize + Debug, { - /// Check if `who` can reserve `value` from their free balance. - /// - /// Always `true` if value to be reserved is zero. - fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { - if value.is_zero() { - return true - } - Self::account(who).free.checked_sub(&value).map_or(false, |new_balance| { - Self::ensure_can_withdraw(who, value, WithdrawReasons::RESERVE, new_balance).is_ok() - }) - } - - fn reserved_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).reserved - } - - /// Move `value` from the free balance from `who` to their reserved balance. - /// - /// Is a no-op if value to be reserved is zero. - fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { - if value.is_zero() { - return Ok(()) - } - - Self::try_mutate_account(who, |account, _| -> DispatchResult { - account.free = - account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; - account.reserved = - account.reserved.checked_add(&value).ok_or(ArithmeticError::Overflow)?; - Self::ensure_can_withdraw(&who, value, WithdrawReasons::RESERVE, account.free) - })?; - - Self::deposit_event(Event::Reserved { who: who.clone(), amount: value }); - Ok(()) - } - - /// Unreserve some funds, returning any amount that was unable to be unreserved. - /// - /// Is a no-op if the value to be unreserved is zero or the account does not exist. - /// - /// NOTE: returns amount value which wasn't successfully unreserved. - fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { - if value.is_zero() { - return Zero::zero() - } - if Self::total_balance(who).is_zero() { - return value - } - - let actual = match Self::mutate_account(who, |account| { - let actual = cmp::min(account.reserved, value); - account.reserved -= actual; - // defensive only: this can never fail since total issuance which is at least - // free+reserved fits into the same data type. - account.free = account.free.defensive_saturating_add(actual); - actual - }) { - Ok(x) => x, - Err(_) => { - // This should never happen since we don't alter the total amount in the account. - // If it ever does, then we should fail gracefully though, indicating that nothing - // could be done. - return value - }, - }; - - Self::deposit_event(Event::Unreserved { who: who.clone(), amount: actual }); - value - actual - } - - /// Slash from reserved balance, returning the negative imbalance created, - /// and any amount that was unable to be slashed. - /// - /// Is a no-op if the value to be slashed is zero or the account does not exist. - fn slash_reserved( - who: &T::AccountId, - value: Self::Balance, - ) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (NegativeImbalance::zero(), Zero::zero()) - } - if Self::total_balance(who).is_zero() { - return (NegativeImbalance::zero(), value) - } - - // NOTE: `mutate_account` may fail if it attempts to reduce the balance to the point that an - // account is attempted to be illegally destroyed. - - for attempt in 0..2 { - match Self::mutate_account(who, |account| { - let best_value = match attempt { - 0 => value, - // If acting as a critical provider (i.e. first attempt failed), then ensure - // slash leaves at least the ED. - _ => value.min( - (account.free + account.reserved) - .saturating_sub(T::ExistentialDeposit::get()), - ), - }; - - let actual = cmp::min(account.reserved, best_value); - account.reserved -= actual; - - // underflow should never happen, but it if does, there's nothing to be done here. - (NegativeImbalance::new(actual), value - actual) - }) { - Ok((imbalance, not_slashed)) => { - Self::deposit_event(Event::Slashed { - who: who.clone(), - amount: value.saturating_sub(not_slashed), - }); - return (imbalance, not_slashed) - }, - Err(_) => (), - } - } - // Should never get here as we ensure that ED is left in the second attempt. - // In case we do, though, then we fail gracefully. - (Self::NegativeImbalance::zero(), value) - } - - /// Move the reserved balance of one account into the balance of another, according to `status`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. - fn repatriate_reserved( - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> Result { - let actual = Self::do_transfer_reserved(slashed, beneficiary, value, true, status)?; - Ok(value.saturating_sub(actual)) - } + /// Check if `who` can reserve `value` from their free balance. + /// + /// Always `true` if value to be reserved is zero. + fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true; + } + Self::account(who) + .free + .checked_sub(&value) + .map_or(false, |new_balance| { + Self::ensure_can_withdraw(who, value, WithdrawReasons::RESERVE, new_balance).is_ok() + }) + } + + fn reserved_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).reserved + } + + /// Move `value` from the free balance from `who` to their reserved balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { + if value.is_zero() { + return Ok(()); + } + + Self::try_mutate_account(who, |account, _| -> DispatchResult { + account.free = account + .free + .checked_sub(&value) + .ok_or(Error::::InsufficientBalance)?; + account.reserved = account + .reserved + .checked_add(&value) + .ok_or(ArithmeticError::Overflow)?; + Self::ensure_can_withdraw(&who, value, WithdrawReasons::RESERVE, account.free) + })?; + + Self::deposit_event(Event::Reserved { + who: who.clone(), + amount: value, + }); + Ok(()) + } + + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero or the account does not exist. + /// + /// NOTE: returns amount value which wasn't successfully unreserved. + fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { + if value.is_zero() { + return Zero::zero(); + } + if Self::total_balance(who).is_zero() { + return value; + } + + let actual = match Self::mutate_account(who, |account| { + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + // defensive only: this can never fail since total issuance which is at least + // free+reserved fits into the same data type. + account.free = account.free.defensive_saturating_add(actual); + actual + }) { + Ok(x) => x, + Err(_) => { + // This should never happen since we don't alter the total amount in the account. + // If it ever does, then we should fail gracefully though, indicating that nothing + // could be done. + return value; + } + }; + + Self::deposit_event(Event::Unreserved { + who: who.clone(), + amount: actual, + }); + value - actual + } + + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero or the account does not exist. + fn slash_reserved( + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()); + } + if Self::total_balance(who).is_zero() { + return (NegativeImbalance::zero(), value); + } + + // NOTE: `mutate_account` may fail if it attempts to reduce the balance to the point that an + // account is attempted to be illegally destroyed. + + for attempt in 0..2 { + match Self::mutate_account(who, |account| { + let best_value = match attempt { + 0 => value, + // If acting as a critical provider (i.e. first attempt failed), then ensure + // slash leaves at least the ED. + _ => value.min( + (account.free + account.reserved) + .saturating_sub(T::ExistentialDeposit::get()), + ), + }; + + let actual = cmp::min(account.reserved, best_value); + account.reserved -= actual; + + // underflow should never happen, but it if does, there's nothing to be done here. + (NegativeImbalance::new(actual), value - actual) + }) { + Ok((imbalance, not_slashed)) => { + Self::deposit_event(Event::Slashed { + who: who.clone(), + amount: value.saturating_sub(not_slashed), + }); + return (imbalance, not_slashed); + } + Err(_) => (), + } + } + // Should never get here as we ensure that ED is left in the second attempt. + // In case we do, though, then we fail gracefully. + (Self::NegativeImbalance::zero(), value) + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + fn repatriate_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + let actual = Self::do_transfer_reserved(slashed, beneficiary, value, true, status)?; + Ok(value.saturating_sub(actual)) + } } impl, I: 'static> NamedReservableCurrency for Pallet where - T::Balance: MaybeSerializeDeserialize + Debug, + T::Balance: MaybeSerializeDeserialize + Debug, { - type ReserveIdentifier = T::ReserveIdentifier; - - fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { - let reserves = Self::reserves(who); - reserves - .binary_search_by_key(id, |data| data.id) - .map(|index| reserves[index].amount) - .unwrap_or_default() - } - - /// Move `value` from the free balance from `who` to a named reserve balance. - /// - /// Is a no-op if value to be reserved is zero. - fn reserve_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> DispatchResult { - if value.is_zero() { - return Ok(()) - } - - Reserves::::try_mutate(who, |reserves| -> DispatchResult { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - // this add can't overflow but just to be defensive. - reserves[index].amount = reserves[index].amount.defensive_saturating_add(value); - }, - Err(index) => { - reserves - .try_insert(index, ReserveData { id: *id, amount: value }) - .map_err(|_| Error::::TooManyReserves)?; - }, - }; - >::reserve(who, value)?; - Ok(()) - }) - } - - /// Unreserve some funds, returning any amount that was unable to be unreserved. - /// - /// Is a no-op if the value to be unreserved is zero. - fn unreserve_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> Self::Balance { - if value.is_zero() { - return Zero::zero() - } - - Reserves::::mutate_exists(who, |maybe_reserves| -> Self::Balance { - if let Some(reserves) = maybe_reserves.as_mut() { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let remain = >::unreserve(who, to_change); - - // remain should always be zero but just to be defensive here. - let actual = to_change.defensive_saturating_sub(remain); - - // `actual <= to_change` and `to_change <= amount`; qed; - reserves[index].amount -= actual; - - if reserves[index].amount.is_zero() { - if reserves.len() == 1 { - // no more named reserves - *maybe_reserves = None; - } else { - // remove this named reserve - reserves.remove(index); - } - } - - value - actual - }, - Err(_) => value, - } - } else { - value - } - }) - } - - /// Slash from reserved balance, returning the negative imbalance created, - /// and any amount that was unable to be slashed. - /// - /// Is a no-op if the value to be slashed is zero. - fn slash_reserved_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (NegativeImbalance::zero(), Zero::zero()) - } - - Reserves::::mutate(who, |reserves| -> (Self::NegativeImbalance, Self::Balance) { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let (imb, remain) = - >::slash_reserved(who, to_change); - - // remain should always be zero but just to be defensive here. - let actual = to_change.defensive_saturating_sub(remain); - - // `actual <= to_change` and `to_change <= amount`; qed; - reserves[index].amount -= actual; - - Self::deposit_event(Event::Slashed { who: who.clone(), amount: actual }); - (imb, value - actual) - }, - Err(_) => (NegativeImbalance::zero(), value), - } - }) - } - - /// Move the reserved balance of one account into the balance of another, according to `status`. - /// If `status` is `Reserved`, the balance will be reserved with given `id`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. - fn repatriate_reserved_named( - id: &Self::ReserveIdentifier, - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> Result { - if value.is_zero() { - return Ok(Zero::zero()) - } - - if slashed == beneficiary { - return match status { - Status::Free => Ok(Self::unreserve_named(id, slashed, value)), - Status::Reserved => - Ok(value.saturating_sub(Self::reserved_balance_named(id, slashed))), - } - } - - Reserves::::try_mutate(slashed, |reserves| -> Result { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let actual = if status == Status::Reserved { - // make it the reserved under same identifier - Reserves::::try_mutate( - beneficiary, - |reserves| -> Result { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let remain = + type ReserveIdentifier = T::ReserveIdentifier; + + fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { + let reserves = Self::reserves(who); + reserves + .binary_search_by_key(id, |data| data.id) + .map(|index| reserves[index].amount) + .unwrap_or_default() + } + + /// Move `value` from the free balance from `who` to a named reserve balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> DispatchResult { + if value.is_zero() { + return Ok(()); + } + + Reserves::::try_mutate(who, |reserves| -> DispatchResult { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + // this add can't overflow but just to be defensive. + reserves[index].amount = reserves[index].amount.defensive_saturating_add(value); + } + Err(index) => { + reserves + .try_insert( + index, + ReserveData { + id: *id, + amount: value, + }, + ) + .map_err(|_| Error::::TooManyReserves)?; + } + }; + >::reserve(who, value)?; + Ok(()) + }) + } + + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero. + fn unreserve_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> Self::Balance { + if value.is_zero() { + return Zero::zero(); + } + + Reserves::::mutate_exists(who, |maybe_reserves| -> Self::Balance { + if let Some(reserves) = maybe_reserves.as_mut() { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let remain = >::unreserve(who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + if reserves[index].amount.is_zero() { + if reserves.len() == 1 { + // no more named reserves + *maybe_reserves = None; + } else { + // remove this named reserve + reserves.remove(index); + } + } + + value - actual + } + Err(_) => value, + } + } else { + value + } + }) + } + + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero. + fn slash_reserved_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()); + } + + Reserves::::mutate( + who, + |reserves| -> (Self::NegativeImbalance, Self::Balance) { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let (imb, remain) = + >::slash_reserved(who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + Self::deposit_event(Event::Slashed { + who: who.clone(), + amount: actual, + }); + (imb, value - actual) + } + Err(_) => (NegativeImbalance::zero(), value), + } + }, + ) + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// If `status` is `Reserved`, the balance will be reserved with given `id`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + fn repatriate_reserved_named( + id: &Self::ReserveIdentifier, + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()); + } + + if slashed == beneficiary { + return match status { + Status::Free => Ok(Self::unreserve_named(id, slashed, value)), + Status::Reserved => { + Ok(value.saturating_sub(Self::reserved_balance_named(id, slashed))) + } + }; + } + + Reserves::::try_mutate( + slashed, + |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let actual = if status == Status::Reserved { + // make it the reserved under same identifier + Reserves::::try_mutate( + beneficiary, + |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let remain = >::repatriate_reserved( slashed, beneficiary, @@ -2081,18 +2269,19 @@ where status, )?; - // remain should always be zero but just to be defensive - // here. - let actual = to_change.defensive_saturating_sub(remain); + // remain should always be zero but just to be defensive + // here. + let actual = to_change.defensive_saturating_sub(remain); - // this add can't overflow but just to be defensive. - reserves[index].amount = - reserves[index].amount.defensive_saturating_add(actual); + // this add can't overflow but just to be defensive. + reserves[index].amount = reserves[index] + .amount + .defensive_saturating_add(actual); - Ok(actual) - }, - Err(index) => { - let remain = + Ok(actual) + } + Err(index) => { + let remain = >::repatriate_reserved( slashed, beneficiary, @@ -2100,110 +2289,122 @@ where status, )?; - // remain should always be zero but just to be defensive - // here - let actual = to_change.defensive_saturating_sub(remain); - - reserves - .try_insert( - index, - ReserveData { id: *id, amount: actual }, - ) - .map_err(|_| Error::::TooManyReserves)?; - - Ok(actual) - }, - } - }, - )? - } else { - let remain = >::repatriate_reserved( - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive here - to_change.defensive_saturating_sub(remain) - }; - - // `actual <= to_change` and `to_change <= amount`; qed; - reserves[index].amount -= actual; - - Ok(value - actual) - }, - Err(_) => Ok(value), - } - }) - } + // remain should always be zero but just to be defensive + // here + let actual = to_change.defensive_saturating_sub(remain); + + reserves + .try_insert( + index, + ReserveData { + id: *id, + amount: actual, + }, + ) + .map_err(|_| Error::::TooManyReserves)?; + + Ok(actual) + } + } + }, + )? + } else { + let remain = >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive here + to_change.defensive_saturating_sub(remain) + }; + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + Ok(value - actual) + } + Err(_) => Ok(value), + } + }, + ) + } } impl, I: 'static> LockableCurrency for Pallet where - T::Balance: MaybeSerializeDeserialize + Debug, + T::Balance: MaybeSerializeDeserialize + Debug, { - type Moment = T::BlockNumber; - - type MaxLocks = T::MaxLocks; - - // Set a lock on the balance of `who`. - // Is a no-op if lock amount is zero or `reasons` `is_none()`. - fn set_lock( - id: LockIdentifier, - who: &T::AccountId, - amount: T::Balance, - reasons: WithdrawReasons, - ) { - if amount.is_zero() || reasons.is_empty() { - return - } - let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); - let mut locks = Self::locks(who) - .into_iter() - .filter_map(|l| if l.id == id { new_lock.take() } else { Some(l) }) - .collect::>(); - if let Some(lock) = new_lock { - locks.push(lock) - } - Self::update_locks(who, &locks[..]); - } - - // Extend a lock on the balance of `who`. - // Is a no-op if lock amount is zero or `reasons` `is_none()`. - fn extend_lock( - id: LockIdentifier, - who: &T::AccountId, - amount: T::Balance, - reasons: WithdrawReasons, - ) { - if amount.is_zero() || reasons.is_empty() { - return - } - let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); - let mut locks = Self::locks(who) - .into_iter() - .filter_map(|l| { - if l.id == id { - new_lock.take().map(|nl| BalanceLock { - id: l.id, - amount: l.amount.max(nl.amount), - reasons: l.reasons | nl.reasons, - }) - } else { - Some(l) - } - }) - .collect::>(); - if let Some(lock) = new_lock { - locks.push(lock) - } - Self::update_locks(who, &locks[..]); - } - - fn remove_lock(id: LockIdentifier, who: &T::AccountId) { - let mut locks = Self::locks(who); - locks.retain(|l| l.id != id); - Self::update_locks(who, &locks[..]); - } + type Moment = T::BlockNumber; + + type MaxLocks = T::MaxLocks; + + // Set a lock on the balance of `who`. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. + fn set_lock( + id: LockIdentifier, + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + ) { + if amount.is_zero() || reasons.is_empty() { + return; + } + let mut new_lock = Some(BalanceLock { + id, + amount, + reasons: reasons.into(), + }); + let mut locks = Self::locks(who) + .into_iter() + .filter_map(|l| if l.id == id { new_lock.take() } else { Some(l) }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(who, &locks[..]); + } + + // Extend a lock on the balance of `who`. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. + fn extend_lock( + id: LockIdentifier, + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + ) { + if amount.is_zero() || reasons.is_empty() { + return; + } + let mut new_lock = Some(BalanceLock { + id, + amount, + reasons: reasons.into(), + }); + let mut locks = Self::locks(who) + .into_iter() + .filter_map(|l| { + if l.id == id { + new_lock.take().map(|nl| BalanceLock { + id: l.id, + amount: l.amount.max(nl.amount), + reasons: l.reasons | nl.reasons, + }) + } else { + Some(l) + } + }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(who, &locks[..]); + } + + fn remove_lock(id: LockIdentifier, who: &T::AccountId) { + let mut locks = Self::locks(who); + locks.retain(|l| l.id != id); + Self::update_locks(who, &locks[..]); + } } diff --git a/pallets/collator-selection/src/mock.rs b/pallets/collator-selection/src/mock.rs index 20ab39a8d..a2b8ee7c6 100644 --- a/pallets/collator-selection/src/mock.rs +++ b/pallets/collator-selection/src/mock.rs @@ -90,6 +90,7 @@ impl pallet_balances::Config for Test { type MaxLocks = (); type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; + type UnixTime = Timestamp; } pub struct Author4; diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index db6562232..6e943beaf 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -107,6 +107,13 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub const ExistentialDeposit: Balance = 1; } @@ -120,6 +127,7 @@ impl pallet_balances::Config for Runtime { type MaxReserves = (); type ReserveIdentifier = [u8; 8]; type WeightInfo = (); + type UnixTime = MockUnixTime; } parameter_types! { diff --git a/pallets/manta-pay/src/mock.rs b/pallets/manta-pay/src/mock.rs index e7738302b..73724de67 100644 --- a/pallets/manta-pay/src/mock.rs +++ b/pallets/manta-pay/src/mock.rs @@ -92,6 +92,13 @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; @@ -108,6 +115,7 @@ impl pallet_balances::Config for Test { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; + type UnixTime = MockUnixTime; } parameter_types! { diff --git a/pallets/manta-sbt/src/mock.rs b/pallets/manta-sbt/src/mock.rs index ff59fbab8..4b60f3c0f 100644 --- a/pallets/manta-sbt/src/mock.rs +++ b/pallets/manta-sbt/src/mock.rs @@ -106,6 +106,13 @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; @@ -122,6 +129,7 @@ impl pallet_balances::Config for Test { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; + type UnixTime = MockUnixTime; } parameter_types! { diff --git a/pallets/name-service/src/mock.rs b/pallets/name-service/src/mock.rs index c870ec8af..81aa94539 100644 --- a/pallets/name-service/src/mock.rs +++ b/pallets/name-service/src/mock.rs @@ -66,6 +66,13 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; @@ -82,6 +89,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; + type UnixTime = MockUnixTime; } parameter_types! { diff --git a/pallets/pallet-lottery/src/mock.rs b/pallets/pallet-lottery/src/mock.rs index 279d8a07c..55aefb418 100644 --- a/pallets/pallet-lottery/src/mock.rs +++ b/pallets/pallet-lottery/src/mock.rs @@ -111,6 +111,13 @@ impl frame_system::Config for Test { type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } + +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} parameter_types! { pub const ExistentialDeposit: u128 = 1; } @@ -124,6 +131,7 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); + type UnixTime = MockUnixTime; } parameter_types! { diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index 10317ad3f..db5932c6e 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -87,6 +87,12 @@ impl frame_system::Config for Test { type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} parameter_types! { pub const ExistentialDeposit: u128 = 1; } @@ -100,6 +106,7 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); + type UnixTime = MockUnixTime; } impl block_author::Config for Test {} parameter_types! { diff --git a/pallets/randomness/src/mock.rs b/pallets/randomness/src/mock.rs index b15ef304f..efd8275a2 100644 --- a/pallets/randomness/src/mock.rs +++ b/pallets/randomness/src/mock.rs @@ -79,6 +79,12 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} parameter_types! { pub const ExistentialDeposit: u128 = 0; } @@ -92,6 +98,7 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); + type UnixTime = MockUnixTime; } pub struct BabeDataGetter; diff --git a/pallets/tx-pause/src/mock.rs b/pallets/tx-pause/src/mock.rs index 13d6de39a..689b3edbf 100644 --- a/pallets/tx-pause/src/mock.rs +++ b/pallets/tx-pause/src/mock.rs @@ -73,6 +73,13 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub const NativeTokenExistentialDeposit: Balance = 10; } @@ -87,6 +94,7 @@ impl pallet_balances::Config for Runtime { type MaxReserves = ConstU32<50>; type ReserveIdentifier = (); type WeightInfo = (); + type UnixTime = MockUnixTime; } ord_parameter_types! { diff --git a/pallets/vesting/src/mock.rs b/pallets/vesting/src/mock.rs index 40cd37bb8..b9206db52 100644 --- a/pallets/vesting/src/mock.rs +++ b/pallets/vesting/src/mock.rs @@ -85,6 +85,7 @@ impl pallet_balances::Config for Test { type MaxReserves = (); type ReserveIdentifier = [u8; 8]; type WeightInfo = (); + type UnixTime = Timestamp; } parameter_types! { diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index f099cd886..c9f4f11e4 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -458,6 +458,7 @@ impl pallet_balances::Config for Runtime { type ExistentialDeposit = NativeTokenExistentialDeposit; type AccountStore = frame_system::Pallet; type WeightInfo = weights::pallet_balances::SubstrateWeight; + type UnixTime = Timestamp; } parameter_types! { @@ -1038,7 +1039,7 @@ extern crate frame_benchmarking; mod benches { frame_benchmarking::define_benchmarks!( // Substrate pallets - [pallet_balances, Balances] + // [pallet_balances, Balances] [pallet_multisig, Multisig] [frame_system, SystemBench::] [pallet_timestamp, Timestamp] diff --git a/runtime/integration-tests/src/integrations_mock/test_calamari.rs b/runtime/integration-tests/src/integrations_mock/test_calamari.rs index 7cf245bf6..b789e24bc 100644 --- a/runtime/integration-tests/src/integrations_mock/test_calamari.rs +++ b/runtime/integration-tests/src/integrations_mock/test_calamari.rs @@ -144,6 +144,20 @@ fn verify_pallet_prefixes() { assert_eq!( ::storage_info(), vec![ + StorageInfo { + pallet_name: b"Balances".to_vec(), + storage_name: b"XcmNativeTransfers".to_vec(), + prefix: prefix(b"Balances", b"XcmNativeTransfers"), + max_values: None, + max_size: Some(72), + }, + StorageInfo { + pallet_name: b"Balances".to_vec(), + storage_name: b"DailyXcmLimit".to_vec(), + prefix: prefix(b"Balances", b"DailyXcmLimit"), + max_values: Some(1), + max_size: Some(16), + }, StorageInfo { pallet_name: b"Balances".to_vec(), storage_name: b"TotalIssuance".to_vec(), diff --git a/runtime/integration-tests/src/integrations_mock/test_manta.rs b/runtime/integration-tests/src/integrations_mock/test_manta.rs index bc70343dc..4dfec16c9 100644 --- a/runtime/integration-tests/src/integrations_mock/test_manta.rs +++ b/runtime/integration-tests/src/integrations_mock/test_manta.rs @@ -106,6 +106,20 @@ fn verify_pallet_prefixes() { assert_eq!( ::storage_info(), vec![ + StorageInfo { + pallet_name: b"Balances".to_vec(), + storage_name: b"XcmNativeTransfers".to_vec(), + prefix: prefix(b"Balances", b"XcmNativeTransfers"), + max_values: None, + max_size: Some(72), + }, + StorageInfo { + pallet_name: b"Balances".to_vec(), + storage_name: b"DailyXcmLimit".to_vec(), + prefix: prefix(b"Balances", b"DailyXcmLimit"), + max_values: Some(1), + max_size: Some(16), + }, StorageInfo { pallet_name: b"Balances".to_vec(), storage_name: b"TotalIssuance".to_vec(), diff --git a/runtime/integration-tests/src/xcm_mock/parachain.rs b/runtime/integration-tests/src/xcm_mock/parachain.rs index f900f9ca3..048124339 100644 --- a/runtime/integration-tests/src/xcm_mock/parachain.rs +++ b/runtime/integration-tests/src/xcm_mock/parachain.rs @@ -108,6 +108,13 @@ impl frame_system::Config for Runtime { type MaxConsumers = ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; @@ -124,6 +131,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; + type UnixTime = MockUnixTime; } parameter_types! { diff --git a/runtime/integration-tests/src/xcm_mock/relay_chain.rs b/runtime/integration-tests/src/xcm_mock/relay_chain.rs index a8ae41597..438fe251c 100644 --- a/runtime/integration-tests/src/xcm_mock/relay_chain.rs +++ b/runtime/integration-tests/src/xcm_mock/relay_chain.rs @@ -78,6 +78,13 @@ impl frame_system::Config for Runtime { type MaxConsumers = ConstU32<16>; } +pub struct MockUnixTime; +impl frame_support::traits::UnixTime for MockUnixTime { + fn now() -> core::time::Duration { + core::time::Duration::default() + } +} + parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; @@ -94,6 +101,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; + type UnixTime = MockUnixTime; } impl pallet_utility::Config for Runtime { diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 9d886819c..38d5bc7e1 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -447,6 +447,7 @@ impl pallet_balances::Config for Runtime { type ExistentialDeposit = NativeTokenExistentialDeposit; type AccountStore = frame_system::Pallet; type WeightInfo = weights::pallet_balances::SubstrateWeight; + type UnixTime = Timestamp; } parameter_types! { @@ -1005,7 +1006,7 @@ extern crate frame_benchmarking; mod benches { frame_benchmarking::define_benchmarks!( // Substrate pallets - [pallet_balances, Balances] + // [pallet_balances, Balances] [pallet_democracy, Democracy] [pallet_collective, Council] [pallet_membership, CouncilMembership] From 6eea3daf2eda60fd4648b3bf2a1d2cc87dc2cb41 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 14 Aug 2023 05:29:51 +0300 Subject: [PATCH 03/69] Add xcmbarrierlist Signed-off-by: Georgi Zlatarev --- pallets/balances/src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 567a020c0..6fbd37cbf 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -461,6 +461,35 @@ pub mod pallet { let _leftover = >::unreserve(&who, amount); Ok(()) } + + /// Transfer the entire transferable balance from the caller account. + /// + /// NOTE: This function only attempts to transfer _transferable_ balances. This means that + /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be + /// transferred by this function. To ensure that this function results in a killed account, + /// you might need to prepare the account by removing any reference counters, storage + /// deposits, etc... + /// + /// The dispatch origin of this call must be Signed. + /// + /// - `dest`: The recipient of the transfer. + /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all + /// of the funds the account has, causing the sender account to be killed (false), or + /// transfer everything except at least the existential deposit, which will guarantee to + /// keep the sender account alive (true). # + /// - O(1). Just like transfer, but reading the user's transferable balance first. + /// # + #[pallet::call_index(6)] + #[pallet::weight(0)] + pub fn add_address_to_barrier( + origin: OriginFor, + account: T::AccountId, + ) -> DispatchResult { + ensure_root(origin)?; + // todo: check if account exists ? + >::insert(account, ()); + Ok(()) + } } #[pallet::event] @@ -557,6 +586,10 @@ pub mod pallet { pub type DailyXcmLimit, I: 'static = ()> = StorageValue<_, T::Balance, OptionQuery>; + #[pallet::storage] + pub type XcmBarrierList, I: 'static = ()> = + StorageMap<_, Identity, T::AccountId, (), OptionQuery>; + /// The total units issued in the system. #[pallet::storage] #[pallet::getter(fn total_issuance)] @@ -817,7 +850,10 @@ impl, I: 'static> Pallet { account_id: &T::AccountId, amount: T::Balance, ) -> DispatchResult { - // check if account_id is in barrier list + // The address is not in the barrier list so we don't care about it + if >::get(account_id) == None { + return Ok(()); + } if let Some(transfer_limit) = >::get() { let now = T::UnixTime::now().as_secs(); From d0966381d470f61fddee1bde079b672df9af1e14 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 14 Aug 2023 07:12:33 +0300 Subject: [PATCH 04/69] Checkpoint Signed-off-by: Georgi Zlatarev --- Cargo.lock | 17 + pallets/balances/Cargo.toml | 3 + pallets/balances/src/lib.rs | 1 + pallets/native-barrier/Cargo.toml | 43 + pallets/native-barrier/README.md | 122 ++ pallets/native-barrier/src/benchmarking.rs | 222 +++ pallets/native-barrier/src/lib.rs | 416 +++++ pallets/native-barrier/src/migration.rs | 103 ++ pallets/native-barrier/src/tests.rs | 1456 +++++++++++++++++ pallets/native-barrier/src/tests_composite.rs | 149 ++ pallets/native-barrier/src/tests_local.rs | 191 +++ .../native-barrier/src/tests_reentrancy.rs | 264 +++ pallets/native-barrier/src/weights.rs | 164 ++ 13 files changed, 3151 insertions(+) create mode 100644 pallets/native-barrier/Cargo.toml create mode 100644 pallets/native-barrier/README.md create mode 100644 pallets/native-barrier/src/benchmarking.rs create mode 100644 pallets/native-barrier/src/lib.rs create mode 100644 pallets/native-barrier/src/migration.rs create mode 100644 pallets/native-barrier/src/tests.rs create mode 100644 pallets/native-barrier/src/tests_composite.rs create mode 100644 pallets/native-barrier/src/tests_local.rs create mode 100644 pallets/native-barrier/src/tests_reentrancy.rs create mode 100644 pallets/native-barrier/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 9bdbc6e4b..8b094fbcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7218,6 +7218,23 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-native-barrier" +version = "4.0.0-dev" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-transaction-payment", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-nis" version = "4.0.0-dev" diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index 2ed128c00..a546ce20c 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -22,6 +22,8 @@ frame-system = { git = 'https://github.com/paritytech/substrate.git', default-fe sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +#pallet-native-barrier = { path = '../native-barrier' } + [dev-dependencies] pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } @@ -38,6 +40,7 @@ std = [ "scale-info/std", "sp-runtime/std", "sp-std/std", + #"pallet-native-barrier/std" ] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 6fbd37cbf..afa18ba21 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -296,6 +296,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; + //>::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; >::transfer( &transactor, diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml new file mode 100644 index 000000000..42380b337 --- /dev/null +++ b/pallets/native-barrier/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "pallet-native-barrier" +version = "4.0.0-dev" +authors = ["Parity Technologies "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://substrate.io" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME pallet to manage balances" +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } +log = { version = "0.4.17", default-features = false } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } +frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } + +[dev-dependencies] +pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "sp-runtime/std", + "sp-std/std", +] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/native-barrier/README.md b/pallets/native-barrier/README.md new file mode 100644 index 000000000..93e424a89 --- /dev/null +++ b/pallets/native-barrier/README.md @@ -0,0 +1,122 @@ +# Balances Module + +The Balances module provides functionality for handling accounts and balances. + +- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) +- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) +- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) + +## Overview + +The Balances module provides functions for: + +- Getting and setting free balances. +- Retrieving total, reserved and unreserved balances. +- Repatriating a reserved balance to a beneficiary account that exists. +- Transferring a balance between accounts (when not reserved). +- Slashing an account balance. +- Account creation and removal. +- Managing total issuance. +- Setting and managing locks. + +### Terminology + +- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents +"dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) + fall below this, then the account is said to be dead; and it loses its functionality as well as any + prior history and all information on it is removed from the chain's state. + No account should ever have a total balance that is strictly between 0 and the existential + deposit (exclusive). If this ever happens, it indicates either a bug in this module or an + erroneous raw mutation of storage. + +- **Total Issuance:** The total number of units in existence in a system. + +- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its +total balance has become zero (or, strictly speaking, less than the Existential Deposit). + +- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only + balance that matters for most operations. + +- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. + Reserved balance can still be slashed, but only after all the free balance has been slashed. + +- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting +(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will +return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is +simply dropped, it should automatically maintain any book-keeping such as total issuance.) + +- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple +locks always operate over the same funds, so they "overlay" rather than "stack". + +### Implementations + +The Balances module provides implementations for the following traits. If these traits provide the functionality +that you need, then you can avoid coupling with the Balances module. + +- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing with a +fungible assets system. +- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): +Functions for dealing with assets that can be reserved from an account. +- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions for +dealing with accounts that allow liquidity restrictions. +- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling +imbalances between total issuance in the system and account balances. Must be used when a function +creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to say whether a +given account is unused. + +## Interface + +### Dispatchable Functions + +- `transfer` - Transfer some liquid free balance to another account. +- `set_balance` - Set the balances of a given account. The origin of this call must be root. + +## Usage + +The following examples show how to use the Balances module in your custom module. + +### Examples from the FRAME + +The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: + +```rust +use frame_support::traits::Currency; + +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; + +``` + +The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: + +```rust +use frame_support::traits::{WithdrawReasons, LockableCurrency}; +use sp_runtime::traits::Bounded; +pub trait Config: frame_system::Config { + type Currency: LockableCurrency; +} + +fn update_ledger( + controller: &T::AccountId, + ledger: &StakingLedger +) { + T::Currency::set_lock( + STAKING_ID, + &ledger.stash, + ledger.total, + WithdrawReasons::all() + ); + // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +} +``` + +## Genesis config + +The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). + +## Assumptions + +* Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. + +License: Apache-2.0 diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs new file mode 100644 index 000000000..164d10d44 --- /dev/null +++ b/pallets/native-barrier/src/benchmarking.rs @@ -0,0 +1,222 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2020-2022 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. + +// //! Balances pallet benchmarking. + +// #![cfg(feature = "runtime-benchmarks")] + +// use super::*; + +// use frame_benchmarking::{account, benchmarks_instance_pallet, whitelisted_caller}; +// use frame_system::RawOrigin; +// use sp_runtime::traits::Bounded; + +// use crate::Pallet as Balances; + +// const SEED: u32 = 0; +// // existential deposit multiplier +// const ED_MULTIPLIER: u32 = 10; + +// benchmarks_instance_pallet! { +// // Benchmark `transfer` extrinsic with the worst possible conditions: +// // * Transfer will kill the sender account. +// // * Transfer will create the recipient account. +// transfer { +// let existential_deposit = T::ExistentialDeposit::get(); +// let caller = whitelisted_caller(); + +// // Give some multiple of the existential deposit +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + +// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, +// // and reap this user. +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); +// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); +// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // Benchmark `transfer` with the best possible condition: +// // * Both accounts exist and will continue to exist. +// #[extra] +// transfer_best_case { +// let caller = whitelisted_caller(); +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + +// // Give the sender account max funds for transfer (their account will never reasonably be killed). +// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + +// // Give the recipient account existential deposit (thus their account already exists). +// let existential_deposit = T::ExistentialDeposit::get(); +// let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); +// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert!(!Balances::::free_balance(&caller).is_zero()); +// assert!(!Balances::::free_balance(&recipient).is_zero()); +// } + +// // Benchmark `transfer_keep_alive` with the worst possible condition: +// // * The recipient account is created. +// transfer_keep_alive { +// let caller = whitelisted_caller(); +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + +// // Give the sender account max funds, thus a transfer will not kill account. +// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); +// let existential_deposit = T::ExistentialDeposit::get(); +// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert!(!Balances::::free_balance(&caller).is_zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // Benchmark `set_balance` coming from ROOT account. This always creates an account. +// set_balance_creating { +// let user: T::AccountId = account("user", 0, SEED); +// let user_lookup = T::Lookup::unlookup(user.clone()); + +// // Give the user some initial balance. +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); +// }: set_balance(RawOrigin::Root, user_lookup, balance_amount, balance_amount) +// verify { +// assert_eq!(Balances::::free_balance(&user), balance_amount); +// assert_eq!(Balances::::reserved_balance(&user), balance_amount); +// } + +// // Benchmark `set_balance` coming from ROOT account. This always kills an account. +// set_balance_killing { +// let user: T::AccountId = account("user", 0, SEED); +// let user_lookup = T::Lookup::unlookup(user.clone()); + +// // Give the user some initial balance. +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); +// }: set_balance(RawOrigin::Root, user_lookup, Zero::zero(), Zero::zero()) +// verify { +// assert!(Balances::::free_balance(&user).is_zero()); +// } + +// // Benchmark `force_transfer` extrinsic with the worst possible conditions: +// // * Transfer will kill the sender account. +// // * Transfer will create the recipient account. +// force_transfer { +// let existential_deposit = T::ExistentialDeposit::get(); +// let source: T::AccountId = account("source", 0, SEED); +// let source_lookup = T::Lookup::unlookup(source.clone()); + +// // Give some multiple of the existential deposit +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&source, balance); + +// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); +// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); +// }: force_transfer(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount) +// verify { +// assert_eq!(Balances::::free_balance(&source), Zero::zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // This benchmark performs the same operation as `transfer` in the worst case scenario, +// // but additionally introduces many new users into the storage, increasing the the merkle +// // trie and PoV size. +// #[extra] +// transfer_increasing_users { +// // 1_000 is not very much, but this upper bound can be controlled by the CLI. +// let u in 0 .. 1_000; +// let existential_deposit = T::ExistentialDeposit::get(); +// let caller = whitelisted_caller(); + +// // Give some multiple of the existential deposit +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + +// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, +// // and reap this user. +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); +// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + +// // Create a bunch of users in storage. +// for i in 0 .. u { +// // The `account` function uses `blake2_256` to generate unique accounts, so these +// // should be quite random and evenly distributed in the trie. +// let new_user: T::AccountId = account("new_user", i, SEED); +// let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); +// } +// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) +// verify { +// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); +// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); +// } + +// // Benchmark `transfer_all` with the worst possible condition: +// // * The recipient account is created +// // * The sender is killed +// transfer_all { +// let caller = whitelisted_caller(); +// let recipient: T::AccountId = account("recipient", 0, SEED); +// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + +// // Give some multiple of the existential deposit +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); +// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, false) +// verify { +// assert!(Balances::::free_balance(&caller).is_zero()); +// assert_eq!(Balances::::free_balance(&recipient), balance); +// } + +// force_unreserve { +// let user: T::AccountId = account("user", 0, SEED); +// let user_lookup = T::Lookup::unlookup(user.clone()); + +// // Give some multiple of the existential deposit +// let existential_deposit = T::ExistentialDeposit::get(); +// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); +// let _ = as Currency<_>>::make_free_balance_be(&user, balance); + +// // Reserve the balance +// as ReservableCurrency<_>>::reserve(&user, balance)?; +// assert_eq!(Balances::::reserved_balance(&user), balance); +// assert!(Balances::::free_balance(&user).is_zero()); + +// }: _(RawOrigin::Root, user_lookup, balance) +// verify { +// assert!(Balances::::reserved_balance(&user).is_zero()); +// assert_eq!(Balances::::free_balance(&user), balance); +// } + +// impl_benchmark_test_suite!( +// Balances, +// crate::tests_composite::ExtBuilder::default().build(), +// crate::tests_composite::Test, +// ) +// } diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs new file mode 100644 index 000000000..aebfb4b1b --- /dev/null +++ b/pallets/native-barrier/src/lib.rs @@ -0,0 +1,416 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2022 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. + +//! # Balances Pallet +//! +//! The Balances pallet provides functionality for handling accounts and balances. +//! +//! - [`Config`] +//! - [`Call`] +//! - [`Pallet`] +//! +//! ## Overview +//! +//! The Balances pallet provides functions for: +//! +//! - Getting and setting free balances. +//! - Retrieving total, reserved and unreserved balances. +//! - Repatriating a reserved balance to a beneficiary account that exists. +//! - Transferring a balance between accounts (when not reserved). +//! - Slashing an account balance. +//! - Account creation and removal. +//! - Managing total issuance. +//! - Setting and managing locks. +//! +//! ### Terminology +//! +//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This +//! prevents "dust accounts" from filling storage. When the free plus the reserved balance (i.e. +//! the total balance) fall below this, then the account is said to be dead; and it loses its +//! functionality as well as any prior history and all information on it is removed from the +//! chain's state. No account should ever have a total balance that is strictly between 0 and the +//! existential deposit (exclusive). If this ever happens, it indicates either a bug in this +//! pallet or an erroneous raw mutation of storage. +//! +//! - **Total Issuance:** The total number of units in existence in a system. +//! +//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after +//! its +//! total balance has become zero (or, strictly speaking, less than the Existential Deposit). +//! +//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only +//! balance that matters for most operations. +//! +//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. +//! Reserved balance can still be slashed, but only after all the free balance has been slashed. +//! +//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite +//! accounting +//! (i.e. a difference between total issuance and account balances). Functions that result in an +//! imbalance will return an object of the `Imbalance` trait that can be managed within your runtime +//! logic. (If an imbalance is simply dropped, it should automatically maintain any book-keeping +//! such as total issuance.) +//! +//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block +//! number. Multiple +//! locks always operate over the same funds, so they "overlay" rather than "stack". +//! +//! ### Implementations +//! +//! The Balances pallet provides implementations for the following traits. If these traits provide +//! the functionality that you need, then you can avoid coupling with the Balances pallet. +//! +//! - [`Currency`](frame_support::traits::Currency): Functions for dealing with a +//! fungible assets system. +//! - [`ReservableCurrency`](frame_support::traits::ReservableCurrency): +//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency): +//! Functions for dealing with assets that can be reserved from an account. +//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for +//! dealing with accounts that allow liquidity restrictions. +//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling +//! imbalances between total issuance in the system and account balances. Must be used when a +//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! - `transfer` - Transfer some liquid free balance to another account. +//! - `set_balance` - Set the balances of a given account. The origin of this call must be root. +//! +//! ## Usage +//! +//! The following examples show how to use the Balances pallet in your custom pallet. +//! +//! ### Examples from the FRAME +//! +//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from +//! `Currency`: +//! +//! ``` +//! use frame_support::traits::Currency; +//! # pub trait Config: frame_system::Config { +//! # type Currency: Currency; +//! # } +//! +//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +//! +//! # fn main() {} +//! ``` +//! +//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds: +//! +//! ``` +//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; +//! use sp_runtime::traits::Bounded; +//! pub trait Config: frame_system::Config { +//! type Currency: LockableCurrency; +//! } +//! # struct StakingLedger { +//! # stash: ::AccountId, +//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, +//! # phantom: std::marker::PhantomData, +//! # } +//! # const STAKING_ID: [u8; 8] = *b"staking "; +//! +//! fn update_ledger( +//! controller: &T::AccountId, +//! ledger: &StakingLedger +//! ) { +//! T::Currency::set_lock( +//! STAKING_ID, +//! &ledger.stash, +//! ledger.total, +//! WithdrawReasons::all() +//! ); +//! // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +//! } +//! # fn main() {} +//! ``` +//! +//! ## Genesis config +//! +//! The Balances pallet depends on the [`GenesisConfig`]. +//! +//! ## Assumptions +//! +//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[macro_use] +mod tests; +mod benchmarking; +pub mod weights; + +use codec::{Codec, MaxEncodedLen}; +#[cfg(feature = "std")] +use frame_support::traits::GenesisBuild; +use frame_support::{ensure, pallet_prelude::DispatchResult, traits::UnixTime}; +use frame_system as system; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}, + FixedPointOperand, +}; +use sp_std::{fmt::Debug, prelude::*}; +pub use weights::WeightInfo; + +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 balance of an account. + type Balance: Parameter + + Member + + AtLeast32BitUnsigned + + Codec + + Default + + Copy + + MaybeSerializeDeserialize + + Debug + + MaxEncodedLen + + TypeInfo + + FixedPointOperand; + + /// The overarching event type. + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// Timestamp provider + type UnixTime: UnixTime; + } + + /// The current storage version. + const STORAGE_VERSION: frame_support::traits::StorageVersion = + frame_support::traits::StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::call] + impl, I: 'static> Pallet { + /// Transfer the entire transferable balance from the caller account. + /// + /// NOTE: This function only attempts to transfer _transferable_ balances. This means that + /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be + /// transferred by this function. To ensure that this function results in a killed account, + /// you might need to prepare the account by removing any reference counters, storage + /// deposits, etc... + /// + /// The dispatch origin of this call must be Signed. + /// + /// - `dest`: The recipient of the transfer. + /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all + /// of the funds the account has, causing the sender account to be killed (false), or + /// transfer everything except at least the existential deposit, which will guarantee to + /// keep the sender account alive (true). # + /// - O(1). Just like transfer, but reading the user's transferable balance first. + /// # + #[pallet::call_index(0)] + #[pallet::weight(0)] + pub fn add_address_to_barrier( + origin: OriginFor, + account: T::AccountId, + ) -> DispatchResult { + ensure_root(origin)?; + // todo: check if account exists ? + >::insert(account, ()); + Ok(()) + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// An account was created with some free balance. + Endowed, + } + + #[pallet::error] + pub enum Error { + /// + XcmTransfersLimitExceeded, + /// + XcmTransfersNotAllowedForAccount, + } + /// Stores amount of native asset XCM transfers and timestamp of last transfer + #[pallet::storage] + pub type XcmNativeTransfers, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, (T::Balance, u64), OptionQuery>; + + /// Stores limit value + #[pallet::storage] + pub type DailyXcmLimit, I: 'static = ()> = + StorageValue<_, T::Balance, OptionQuery>; + + #[pallet::storage] + pub type XcmBarrierList, I: 'static = ()> = + StorageMap<_, Identity, T::AccountId, (), OptionQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + pub balances: Vec<(T::AccountId, T::Balance)>, + } + + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { + balances: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) {} + } +} + +#[cfg(feature = "std")] +impl, I: 'static> GenesisConfig { + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + >::assimilate_storage(self, storage) + } +} + +const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day + +pub trait NativeBarrier { + fn update_xcm_native_transfers(account_id: &AccountId, amount: Balance); + fn ensure_xcm_transfer_limit_not_exceeded( + account_id: &AccountId, + amount: Balance, + ) -> DispatchResult; +} + +impl, I: 'static> NativeBarrier for Pallet { + fn ensure_xcm_transfer_limit_not_exceeded( + account_id: &T::AccountId, + amount: T::Balance, + ) -> DispatchResult { + // The address is not in the barrier list so we don't care about it + if >::get(account_id) == None { + return Ok(()); + } + + if let Some(transfer_limit) = >::get() { + let now = T::UnixTime::now().as_secs(); + let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; + let (mut transferred, last_transfer) = >::get(account_id) + .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + + if last_transfer < current_period { + transferred = Default::default(); + >::insert(account_id, (transferred, now)); + }; + + ensure!( + transferred + amount <= transfer_limit, + Error::::XcmTransfersLimitExceeded + ); + + Self::update_xcm_native_transfers(account_id, amount) + } + + Ok(()) + } + + fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { + if >::get().is_some() { + >::mutate_exists(account_id, |maybe_transfer| { + match maybe_transfer { + Some((current_amount, last_transfer)) => { + *current_amount = *current_amount + amount; + *last_transfer = T::UnixTime::now().as_secs(); + } + None => {} + } + }); + } + } +} + +// impl, I: 'static> Pallet { +// // fn ensure_xcm_transfer_limit_not_exceeded( +// // account_id: &T::AccountId, +// // amount: T::Balance, +// // ) -> DispatchResult { +// // // The address is not in the barrier list so we don't care about it +// // if >::get(account_id) == None { +// // return Ok(()); +// // } + +// // if let Some(transfer_limit) = >::get() { +// // let now = T::UnixTime::now().as_secs(); +// // let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; +// // let (mut transferred, last_transfer) = >::get(account_id) +// // .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + +// // if last_transfer < current_period { +// // transferred = Default::default(); +// // >::insert(account_id, (transferred, now)); +// // }; + +// // ensure!( +// // transferred + amount <= transfer_limit, +// // Error::::XcmTransfersLimitExceeded +// // ); + +// // Self::update_xcm_native_transfers(account_id, amount) +// // } + +// // Ok(()) +// // } + +// // fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { +// // if >::get().is_some() { +// // >::mutate_exists(account_id, |maybe_transfer| { +// // match maybe_transfer { +// // Some((current_amount, last_transfer)) => { +// // *current_amount = *current_amount + amount; +// // *last_transfer = T::UnixTime::now().as_secs(); +// // } +// // None => {} +// // } +// // }); +// // } +// // } +// } diff --git a/pallets/native-barrier/src/migration.rs b/pallets/native-barrier/src/migration.rs new file mode 100644 index 000000000..6d47a16f4 --- /dev/null +++ b/pallets/native-barrier/src/migration.rs @@ -0,0 +1,103 @@ +// // Copyright 2017-2020 Parity Technologies (UK) Ltd. +// // This file is part of Polkadot. + +// // Polkadot is free software: you can redistribute it and/or modify +// // it under the terms of the GNU General Public License as published by +// // the Free Software Foundation, either version 3 of the License, or +// // (at your option) any later version. + +// // Polkadot is distributed in the hope that it will be useful, +// // but WITHOUT ANY WARRANTY; without even the implied warranty of +// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// // GNU General Public License for more details. + +// // You should have received a copy of the GNU General Public License +// // along with Polkadot. If not, see . + +// use super::*; +// use frame_support::{ +// pallet_prelude::*, +// traits::{OnRuntimeUpgrade, PalletInfoAccess}, +// weights::Weight, +// }; + +// fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { +// let onchain_version = Pallet::::on_chain_storage_version(); + +// if onchain_version == 0 { +// let total = accounts +// .iter() +// .map(|a| Pallet::::total_balance(a)) +// .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); +// Pallet::::deactivate(total); + +// // Remove the old `StorageVersion` type. +// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( +// Pallet::::name().as_bytes(), +// "StorageVersion".as_bytes(), +// )); + +// // Set storage version to `1`. +// StorageVersion::new(1).put::>(); + +// log::info!(target: LOG_TARGET, "Storage to version 1"); +// T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) +// } else { +// log::info!( +// target: LOG_TARGET, +// "Migration did not execute. This probably should be removed" +// ); +// T::DbWeight::get().reads(1) +// } +// } + +// // NOTE: This must be used alongside the account whose balance is expected to be inactive. +// // Generally this will be used for the XCM teleport checking account. +// pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); +// impl, A: Get, I: 'static> OnRuntimeUpgrade +// for MigrateToTrackInactive +// { +// fn on_runtime_upgrade() -> Weight { +// migrate_v0_to_v1::(&[A::get()]) +// } +// } + +// // NOTE: This must be used alongside the accounts whose balance is expected to be inactive. +// // Generally this will be used for the XCM teleport checking accounts. +// pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); +// impl, A: Get>, I: 'static> OnRuntimeUpgrade +// for MigrateManyToTrackInactive +// { +// fn on_runtime_upgrade() -> Weight { +// migrate_v0_to_v1::(&A::get()) +// } +// } + +// pub struct ResetInactive(PhantomData<(T, I)>); +// impl, I: 'static> OnRuntimeUpgrade for ResetInactive { +// fn on_runtime_upgrade() -> Weight { +// let onchain_version = Pallet::::on_chain_storage_version(); + +// if onchain_version == 1 { +// // Remove the old `StorageVersion` type. +// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( +// Pallet::::name().as_bytes(), +// "StorageVersion".as_bytes(), +// )); + +// InactiveIssuance::::kill(); + +// // Set storage version to `0`. +// StorageVersion::new(0).put::>(); + +// log::info!(target: LOG_TARGET, "Storage to version 0"); +// T::DbWeight::get().reads_writes(1, 2) +// } else { +// log::info!( +// target: LOG_TARGET, +// "Migration did not execute. This probably should be removed" +// ); +// T::DbWeight::get().reads(1) +// } +// } +// } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs new file mode 100644 index 000000000..2869b547d --- /dev/null +++ b/pallets/native-barrier/src/tests.rs @@ -0,0 +1,1456 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2017-2022 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. + +// //! Macro for creating the tests for the module. + +// #![cfg(test)] + +// #[macro_export] +// macro_rules! decl_tests { +// ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { + +// use crate::*; +// use sp_runtime::{ArithmeticError, TokenError, FixedPointNumber, traits::{SignedExtension, BadOrigin}}; +// use frame_support::{ +// assert_noop, assert_storage_noop, assert_ok, assert_err, +// traits::{ +// LockableCurrency, LockIdentifier, WithdrawReasons, +// Currency, ReservableCurrency, ExistenceRequirement::AllowDeath +// } +// }; +// use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; +// use frame_system::RawOrigin; + +// const ID_1: LockIdentifier = *b"1 "; +// const ID_2: LockIdentifier = *b"2 "; + +// pub const CALL: &<$test as frame_system::Config>::RuntimeCall = +// &RuntimeCall::Balances(pallet_balances::Call::transfer { dest: 0, value: 0 }); + +// /// create a transaction info struct from weight. Handy to avoid building the whole struct. +// pub fn info_from_weight(w: Weight) -> DispatchInfo { +// DispatchInfo { weight: w, ..Default::default() } +// } + +// fn events() -> Vec { +// let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + +// System::reset_events(); + +// evt +// } + +// #[test] +// fn basic_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// assert_eq!(Balances::free_balance(1), 10); +// Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 5, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn account_should_be_reaped() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// assert_eq!(Balances::free_balance(1), 10); +// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); +// // Check that the account is dead. +// assert!(!frame_system::Account::::contains_key(&1)); +// }); +// } + +// #[test] +// fn reap_failed_due_to_provider_and_consumer() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// // SCENARIO: only one provider and there are remaining consumers. +// assert_ok!(System::inc_consumers(&1)); +// assert!(!System::can_dec_provider(&1)); +// assert_noop!( +// >::transfer(&1, &2, 10, AllowDeath), +// Error::<$test, _>::KeepAlive +// ); +// assert!(System::account_exists(&1)); +// assert_eq!(Balances::free_balance(1), 10); + +// // SCENARIO: more than one provider, but will not kill account due to other provider. +// assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); +// assert_eq!(System::providers(&1), 2); +// assert!(System::can_dec_provider(&1)); +// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); +// assert_eq!(System::providers(&1), 1); +// assert!(System::account_exists(&1)); +// assert_eq!(Balances::free_balance(1), 0); +// }); +// } + +// #[test] +// fn partial_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn lock_removal_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); +// Balances::remove_lock(ID_1, &1); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn lock_replacement_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn double_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn combination_locking_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); +// Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// }); +// } + +// #[test] +// fn lock_value_extension_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 3, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn lock_reasons_should_work() { +// <$ext_builder>::default() +// .existential_deposit(1) +// .monied(true) +// .build() +// .execute_with(|| { +// pallet_transaction_payment::NextFeeMultiplier::<$test>::put( +// Multiplier::saturating_from_integer(1) +// ); +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); +// assert_noop!( +// >::transfer(&1, &2, 1, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// assert_noop!( +// >::reserve(&1, 1), +// Error::<$test, _>::LiquidityRestrictions, +// ); +// assert!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(1), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// ).is_err()); +// assert_ok!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(0), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// )); + +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); +// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); +// assert_ok!(>::reserve(&1, 1)); +// assert!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(1), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// ).is_err()); +// assert!( as SignedExtension>::pre_dispatch( +// ChargeTransactionPayment::from(0), +// &1, +// CALL, +// &info_from_weight(Weight::from_ref_time(1)), +// 1, +// ).is_err()); +// }); +// } + +// #[test] +// fn lock_block_number_extension_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// System::set_block_number(2); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); +// assert_noop!( +// >::transfer(&1, &2, 3, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn lock_reasons_extension_should_work() { +// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { +// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); +// assert_noop!( +// >::transfer(&1, &2, 6, AllowDeath), +// Error::<$test, _>::LiquidityRestrictions +// ); +// }); +// } + +// #[test] +// fn default_indexing_on_new_accounts_should_not_work2() { +// <$ext_builder>::default() +// .existential_deposit(10) +// .monied(true) +// .build() +// .execute_with(|| { +// // account 5 should not exist +// // ext_deposit is 10, value is 9, not satisfies for ext_deposit +// assert_noop!( +// Balances::transfer(Some(1).into(), 5, 9), +// Error::<$test, _>::ExistentialDeposit, +// ); +// assert_eq!(Balances::free_balance(1), 100); +// }); +// } + +// #[test] +// fn reserved_balance_should_prevent_reclaim_count() { +// <$ext_builder>::default() +// .existential_deposit(256 * 1) +// .monied(true) +// .build() +// .execute_with(|| { +// System::inc_account_nonce(&2); +// assert_eq!(Balances::total_balance(&2), 256 * 20); + +// assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved +// assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." +// assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. +// assert_eq!(System::account_nonce(&2), 1); + +// // account 4 tries to take index 1 for account 5. +// assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); +// assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); + +// assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed +// // "reserve" account reduced to 255 (below ED) so account deleted +// assert_eq!(Balances::total_balance(&2), 0); +// assert_eq!(System::account_nonce(&2), 0); // nonce zero + +// // account 4 tries to take index 1 again for account 6. +// assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); +// assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); +// }); +// } + +// #[test] +// fn reward_should_work() { +// <$ext_builder>::default().monied(true).build().execute_with(|| { +// assert_eq!(Balances::total_balance(&1), 10); +// assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 })); +// assert_eq!(Balances::total_balance(&1), 20); +// assert_eq!(>::get(), 120); +// }); +// } + +// #[test] +// fn dust_account_removal_should_work() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .monied(true) +// .build() +// .execute_with(|| { +// System::inc_account_nonce(&2); +// assert_eq!(System::account_nonce(&2), 1); +// assert_eq!(Balances::total_balance(&2), 2000); +// // index 1 (account 2) becomes zombie +// assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); +// assert_eq!(Balances::total_balance(&2), 0); +// assert_eq!(Balances::total_balance(&5), 1901); +// assert_eq!(System::account_nonce(&2), 0); +// }); +// } + +// #[test] +// fn balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 42); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 42 })); +// assert_eq!(Balances::free_balance(1), 42); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(Balances::total_balance(&1), 42); +// assert_eq!(Balances::free_balance(2), 0); +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::total_balance(&2), 0); +// }); +// } + +// #[test] +// fn balance_transfer_works() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); +// assert_eq!(Balances::total_balance(&1), 42); +// assert_eq!(Balances::total_balance(&2), 69); +// }); +// } + +// #[test] +// fn force_transfer_works() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_noop!( +// Balances::force_transfer(Some(2).into(), 1, 2, 69), +// BadOrigin, +// ); +// assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); +// assert_eq!(Balances::total_balance(&1), 42); +// assert_eq!(Balances::total_balance(&2), 69); +// }); +// } + +// #[test] +// fn reserving_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 111); +// assert_eq!(Balances::reserved_balance(1), 0); + +// assert_ok!(Balances::reserve(&1, 69)); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 42); +// assert_eq!(Balances::reserved_balance(1), 69); +// }); +// } + +// #[test] +// fn balance_transfer_when_reserved_should_not_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 69)); +// assert_noop!( +// Balances::transfer(Some(1).into(), 2, 69), +// Error::<$test, _>::InsufficientBalance, +// ); +// }); +// } + +// #[test] +// fn deducting_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 69)); +// assert_eq!(Balances::free_balance(1), 42); +// }); +// } + +// #[test] +// fn refunding_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 42); +// assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); +// Balances::unreserve(&1, 69); +// assert_eq!(Balances::free_balance(1), 111); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn slashing_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 69)); +// assert!(Balances::slash(&1, 69).1.is_zero()); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 42); +// assert_eq!(>::get(), 42); +// }); +// } + +// #[test] +// fn withdrawing_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&2, 111); +// let _ = Balances::withdraw( +// &2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive +// ); +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Withdraw { who: 2, amount: 11 })); +// assert_eq!(Balances::free_balance(2), 100); +// assert_eq!(>::get(), 100); +// }); +// } + +// #[test] +// fn slashing_incomplete_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 42); +// assert_ok!(Balances::reserve(&1, 21)); +// assert_eq!(Balances::slash(&1, 69).1, 27); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(>::get(), 0); +// }); +// } + +// #[test] +// fn unreserving_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 111)); +// Balances::unreserve(&1, 42); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 42); +// }); +// } + +// #[test] +// fn slashing_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 111)); +// assert_eq!(Balances::slash_reserved(&1, 42).1, 0); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(>::get(), 69); +// }); +// } + +// #[test] +// fn slashing_incomplete_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 42)); +// assert_eq!(Balances::slash_reserved(&1, 69).1, 27); +// assert_eq!(Balances::free_balance(1), 69); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(>::get(), 69); +// }); +// } + +// #[test] +// fn repatriating_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 1); +// assert_ok!(Balances::reserve(&1, 110)); +// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); +// System::assert_last_event( +// RuntimeEvent::Balances(crate::Event::ReserveRepatriated { from: 1, to: 2, amount: 41, destination_status: Status::Free }) +// ); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::free_balance(2), 42); +// }); +// } + +// #[test] +// fn transferring_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 1); +// assert_ok!(Balances::reserve(&1, 110)); +// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); +// assert_eq!(Balances::reserved_balance(1), 69); +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(2), 41); +// assert_eq!(Balances::free_balance(2), 1); +// }); +// } + +// #[test] +// fn transferring_reserved_balance_to_yourself_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// assert_ok!(Balances::reserve(&1, 50)); +// assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Status::Free), 0); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance(1), 0); + +// assert_ok!(Balances::reserve(&1, 50)); +// assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Status::Free), 10); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn transferring_reserved_balance_to_nonexistent_should_fail() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(Balances::reserve(&1, 111)); +// assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); +// }); +// } + +// #[test] +// fn transferring_incomplete_reserved_balance_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 1); +// assert_ok!(Balances::reserve(&1, 41)); +// assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Status::Free), 28); +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(Balances::free_balance(1), 69); +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::free_balance(2), 42); +// }); +// } + +// #[test] +// fn transferring_too_high_value_should_not_panic() { +// <$ext_builder>::default().build().execute_with(|| { +// Balances::make_free_balance_be(&1, u64::MAX); +// Balances::make_free_balance_be(&2, 1); + +// assert_err!( +// Balances::transfer(Some(1).into(), 2, u64::MAX), +// ArithmeticError::Overflow, +// ); + +// assert_eq!(Balances::free_balance(1), u64::MAX); +// assert_eq!(Balances::free_balance(2), 1); +// }); +// } + +// #[test] +// fn account_create_on_free_too_low_with_other() { +// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 100); +// assert_eq!(>::get(), 100); + +// // No-op. +// let _ = Balances::deposit_creating(&2, 50); +// assert_eq!(Balances::free_balance(2), 0); +// assert_eq!(>::get(), 100); +// }) +// } + +// #[test] +// fn account_create_on_free_too_low() { +// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { +// // No-op. +// let _ = Balances::deposit_creating(&2, 50); +// assert_eq!(Balances::free_balance(2), 0); +// assert_eq!(>::get(), 0); +// }) +// } + +// #[test] +// fn account_removal_on_free_too_low() { +// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { +// assert_eq!(>::get(), 0); + +// // Setup two accounts with free balance above the existential threshold. +// let _ = Balances::deposit_creating(&1, 110); +// let _ = Balances::deposit_creating(&2, 110); + +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::free_balance(2), 110); +// assert_eq!(>::get(), 220); + +// // Transfer funds from account 1 of such amount that after this transfer +// // the balance of account 1 will be below the existential threshold. +// // This should lead to the removal of all balance of this account. +// assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); + +// // Verify free balance removal of account 1. +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::free_balance(2), 130); + +// // Verify that TotalIssuance tracks balance removal when free balance is too low. +// assert_eq!(>::get(), 130); +// }); +// } + +// #[test] +// fn burn_must_work() { +// <$ext_builder>::default().monied(true).build().execute_with(|| { +// let init_total_issuance = Balances::total_issuance(); +// let imbalance = Balances::burn(10); +// assert_eq!(Balances::total_issuance(), init_total_issuance - 10); +// drop(imbalance); +// assert_eq!(Balances::total_issuance(), init_total_issuance); +// }); +// } + +// #[test] +// fn transfer_keep_alive_works() { +// <$ext_builder>::default().existential_deposit(1).build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 100); +// assert_noop!( +// Balances::transfer_keep_alive(Some(1).into(), 2, 100), +// Error::<$test, _>::KeepAlive +// ); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 0); +// }); +// } + +// #[test] +// #[should_panic = "the balance of any account should always be at least the existential deposit."] +// fn cannot_set_genesis_value_below_ed() { +// ($existential_deposit).with(|v| *v.borrow_mut() = 11); +// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); +// let _ = pallet_balances::GenesisConfig::<$test> { +// balances: vec![(1, 10)], +// }.assimilate_storage(&mut t).unwrap(); +// } + +// #[test] +// #[should_panic = "duplicate balances in genesis."] +// fn cannot_set_genesis_value_twice() { +// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); +// let _ = pallet_balances::GenesisConfig::<$test> { +// balances: vec![(1, 10), (2, 20), (1, 15)], +// }.assimilate_storage(&mut t).unwrap(); +// } + +// #[test] +// fn dust_moves_between_free_and_reserved() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// // Set balance to free and reserved at the existential deposit +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); +// // Check balance +// assert_eq!(Balances::free_balance(1), 100); +// assert_eq!(Balances::reserved_balance(1), 0); + +// // Reserve some free balance +// assert_ok!(Balances::reserve(&1, 50)); +// // Check balance, the account should be ok. +// assert_eq!(Balances::free_balance(1), 50); +// assert_eq!(Balances::reserved_balance(1), 50); + +// // Reserve the rest of the free balance +// assert_ok!(Balances::reserve(&1, 50)); +// // Check balance, the account should be ok. +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 100); + +// // Unreserve everything +// Balances::unreserve(&1, 100); +// // Check balance, all 100 should move to free_balance +// assert_eq!(Balances::free_balance(1), 100); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn account_deleted_when_just_dust() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// // Set balance to free and reserved at the existential deposit +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 50, 50)); +// // Check balance +// assert_eq!(Balances::free_balance(1), 50); +// assert_eq!(Balances::reserved_balance(1), 50); + +// // Reserve some free balance +// let res = Balances::slash(&1, 1); +// assert_eq!(res, (NegativeImbalance::new(1), 0)); + +// // The account should be dead. +// assert_eq!(Balances::free_balance(1), 0); +// assert_eq!(Balances::reserved_balance(1), 0); +// }); +// } + +// #[test] +// fn emit_events_with_reserve_and_unreserve() { +// <$ext_builder>::default() +// .build() +// .execute_with(|| { +// let _ = Balances::deposit_creating(&1, 100); + +// System::set_block_number(2); +// assert_ok!(Balances::reserve(&1, 10)); + +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { who: 1, amount: 10 })); + +// System::set_block_number(3); +// assert!(Balances::unreserve(&1, 5).is_zero()); + +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); + +// System::set_block_number(4); +// assert_eq!(Balances::unreserve(&1, 6), 1); + +// // should only unreserve 5 +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); +// }); +// } + +// #[test] +// fn emit_events_with_existential_deposit() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), +// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), +// ] +// ); + +// let res = Balances::slash(&1, 1); +// assert_eq!(res, (NegativeImbalance::new(1), 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), +// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), +// ] +// ); +// }); +// } + +// #[test] +// fn emit_events_with_no_existential_deposit_suicide() { +// <$ext_builder>::default() +// .existential_deposit(1) +// .build() +// .execute_with(|| { +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), +// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), +// ] +// ); + +// let res = Balances::slash(&1, 100); +// assert_eq!(res, (NegativeImbalance::new(100), 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), +// ] +// ); +// }); +// } + +// #[test] +// fn slash_loop_works() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// /* User has no reference counter, so they can die in these scenarios */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 900 })); + +// // SCENARIO: Slash will kill account because not enough balance left. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); +// // Account is killed +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash will kill account, and report missing slash amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed full free_balance, and reports 300 not slashed +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); +// // Account is dead +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, but keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, and kill. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); +// // Account is dead because 50 reserved balance is not enough to keep alive +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash can take as much as possible from reserved, kill, and report missing amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); +// // Account is super dead +// assert!(!System::account_exists(&1)); + +// /* User will now have a reference counter on them, keeping them alive in these scenarios */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Slash will take as much as possible without killing account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed completed in full +// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(900), 50)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash will not kill account, and report missing slash amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); +// // Slashed full free_balance minus ED, and reports 400 not slashed +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(900), 400)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, but keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take from reserved, but keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); +// // Slashed full free_balance and 250 of reserved balance to leave ED +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash can take as much as possible from reserved and report missing amount. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); +// // Slashed full free_balance and 300 of reserved balance +// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1150), 150)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // Slash on non-existent account is okay. +// assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); +// }); +// } + +// #[test] +// fn slash_reserved_loop_works() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// /* User has no reference counter, so they can die in these scenarios */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Slash would kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(1_000), 0)); +// // Account is dead +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash would kill account, and reports left over slash. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); +// // Account is dead +// assert!(!System::account_exists(&1)); + +// // SCENARIO: Over-slash does not take from free balance. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 300, 1_000)); +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); +// // Account is alive because of free balance +// assert!(System::account_exists(&1)); + +// /* User has a reference counter, so they cannot die */ +// // SCENARIO: Slash would not kill account. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests +// // Slashed completed in full +// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Slash as much as possible without killing. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed as much as possible +// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(950), 50)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash reports correctly, where reserved is needed to keep alive. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); +// // Slashed as much as possible +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(950), 350)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // SCENARIO: Over-slash reports correctly, where full reserved is removed. +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 1_000)); +// // Slashed as much as possible +// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); +// // Account is still alive +// assert!(System::account_exists(&1)); + +// // Slash on non-existent account is okay. +// assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); +// }); +// } + +// #[test] +// fn operations_on_dead_account_should_not_change_state() { +// // These functions all use `mutate_account` which may introduce a storage change when +// // the account never existed to begin with, and shouldn't exist in the end. +// <$ext_builder>::default() +// .existential_deposit(0) +// .build() +// .execute_with(|| { +// assert!(!frame_system::Account::::contains_key(&1337)); + +// // Unreserve +// assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); +// // Reserve +// assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); +// // Slash Reserve +// assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); +// // Repatriate Reserve +// assert_noop!(Balances::repatriate_reserved(&1337, &1338, 42, Status::Free), Error::::DeadAccount); +// // Slash +// assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); +// }); +// } + +// #[test] +// fn transfer_keep_alive_all_free_succeed() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 100, 100)); +// assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 100); +// }); +// } + +// #[test] +// fn transfer_all_works() { +// <$ext_builder>::default() +// .existential_deposit(100) +// .build() +// .execute_with(|| { +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and allow death +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); +// assert_eq!(Balances::total_balance(&1), 0); +// assert_eq!(Balances::total_balance(&2), 200); + +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and keep alive +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 100); + +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and allow death w/ reserved +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); +// assert_eq!(Balances::total_balance(&1), 0); +// assert_eq!(Balances::total_balance(&2), 200); + +// // setup +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); +// // transfer all and keep alive w/ reserved +// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); +// assert_eq!(Balances::total_balance(&1), 100); +// assert_eq!(Balances::total_balance(&2), 110); +// }); +// } + +// #[test] +// fn named_reserve_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id_1 = [1u8; 8]; +// let id_2 = [2u8; 8]; +// let id_3 = [3u8; 8]; + +// // reserve + +// assert_noop!(Balances::reserve_named(&id_1, &1, 112), Error::::InsufficientBalance); + +// assert_ok!(Balances::reserve_named(&id_1, &1, 12)); + +// assert_eq!(Balances::reserved_balance(1), 12); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + +// assert_ok!(Balances::reserve_named(&id_1, &1, 2)); + +// assert_eq!(Balances::reserved_balance(1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + +// assert_ok!(Balances::reserve_named(&id_2, &1, 23)); + +// assert_eq!(Balances::reserved_balance(1), 37); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_ok!(Balances::reserve(&1, 34)); + +// assert_eq!(Balances::reserved_balance(1), 71); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 40); + +// assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); + +// // unreserve + +// assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); + +// assert_eq!(Balances::reserved_balance(1), 61); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); + +// assert_eq!(Balances::reserved_balance(1), 57); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + +// assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); + +// assert_eq!(Balances::reserved_balance(1), 54); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); + +// assert_eq!(Balances::total_balance(&1), 111); +// assert_eq!(Balances::free_balance(1), 57); + +// // slash_reserved_named + +// assert_ok!(Balances::reserve_named(&id_1, &1, 10)); + +// assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); + +// assert_eq!(Balances::reserved_balance(1), 54); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); +// assert_eq!(Balances::total_balance(&1), 101); + +// assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); + +// assert_eq!(Balances::reserved_balance(1), 49); +// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); +// assert_eq!(Balances::total_balance(&1), 96); + +// // repatriate_reserved_named + +// let _ = Balances::deposit_creating(&2, 100); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Reserved).unwrap(), 0); + +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); +// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); +// assert_eq!(Balances::reserved_balance(&2), 10); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Status::Reserved).unwrap(), 1); + +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); +// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); +// assert_eq!(Balances::reserved_balance(&2), 0); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Free).unwrap(), 0); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); +// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); +// assert_eq!(Balances::free_balance(&2), 110); + +// // repatriate_reserved_named to self + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Status::Reserved).unwrap(), 5); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + +// assert_eq!(Balances::free_balance(&1), 47); + +// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Status::Free).unwrap(), 10); +// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + +// assert_eq!(Balances::free_balance(&1), 52); +// }); +// } + +// #[test] +// fn reserved_named_to_yourself_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 110); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 50)); +// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Status::Free), 0); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + +// assert_ok!(Balances::reserve_named(&id, &1, 50)); +// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Status::Free), 10); +// assert_eq!(Balances::free_balance(1), 110); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// }); +// } + +// #[test] +// fn ensure_reserved_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 15); + +// assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 10); + +// assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 20); +// }); +// } + +// #[test] +// fn unreserve_all_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 15)); + +// assert_eq!(Balances::unreserve_all_named(&id, &1), 15); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// assert_eq!(Balances::free_balance(&1), 111); + +// assert_eq!(Balances::unreserve_all_named(&id, &1), 0); +// }); +// } + +// #[test] +// fn slash_all_reserved_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 15)); + +// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// assert_eq!(Balances::free_balance(&1), 96); + +// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); +// }); +// } + +// #[test] +// fn repatriate_all_reserved_named_should_work() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// let _ = Balances::deposit_creating(&2, 10); +// let _ = Balances::deposit_creating(&3, 10); + +// let id = [1u8; 8]; + +// assert_ok!(Balances::reserve_named(&id, &1, 15)); + +// assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Status::Reserved)); +// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); +// assert_eq!(Balances::reserved_balance_named(&id, &2), 15); + +// assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Status::Free)); +// assert_eq!(Balances::reserved_balance_named(&id, &2), 0); +// assert_eq!(Balances::free_balance(&3), 25); +// }); +// } + +// #[test] +// fn set_balance_handles_killing_account() { +// <$ext_builder>::default().build().execute_with(|| { +// let _ = Balances::deposit_creating(&1, 111); +// assert_ok!(frame_system::Pallet::::inc_consumers(&1)); +// assert_noop!( +// Balances::set_balance(RuntimeOrigin::root(), 1, 0, 0), +// DispatchError::ConsumerRemaining, +// ); +// }); +// } + +// #[test] +// fn set_balance_handles_total_issuance() { +// <$ext_builder>::default().build().execute_with(|| { +// let old_total_issuance = Balances::total_issuance(); +// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1337, 69, 42)); +// assert_eq!(Balances::total_issuance(), old_total_issuance + 69 + 42); +// assert_eq!(Balances::total_balance(&1337), 69 + 42); +// assert_eq!(Balances::free_balance(&1337), 69); +// assert_eq!(Balances::reserved_balance(&1337), 42); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_set_balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_eq!(>::balance(&1337), 0); +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!(>::balance(&1337), 100); + +// assert_ok!(Balances::reserve(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); + +// assert_noop!(>::set_balance(&1337, 0), ArithmeticError::Underflow); + +// assert_ok!(>::set_balance(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 0); +// assert_eq!(Balances::reserved_balance(1337), 60); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_set_total_issuance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_eq!(>::total_issuance(), 0); +// >::set_total_issuance(100); +// assert_eq!(>::total_issuance(), 100); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_decrease_balance_simple_works() { +// <$ext_builder>::default().build().execute_with(|| { +// // An Account that starts at 100 +// assert_ok!(>::set_balance(&1337, 100)); +// // and reserves 50 +// assert_ok!(Balances::reserve(&1337, 50)); +// // and is decreased by 20 +// assert_ok!(>::decrease_balance(&1337, 20)); +// // should end up at 80. +// assert_eq!(>::balance(&1337), 80); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_decrease_balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!(>::balance(&1337), 100); + +// assert_noop!( +// >::decrease_balance(&1337, 101), +// TokenError::NoFunds +// ); +// assert_eq!( +// >::decrease_balance(&1337, 100), +// Ok(100) +// ); +// assert_eq!(>::balance(&1337), 0); + +// // free: 40, reserved: 60 +// assert_ok!(>::set_balance(&1337, 100)); +// assert_ok!(Balances::reserve(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); +// assert_noop!( +// >::decrease_balance(&1337, 41), +// TokenError::NoFunds +// ); +// assert_eq!( +// >::decrease_balance(&1337, 40), +// Ok(40) +// ); +// assert_eq!(>::balance(&1337), 60); +// assert_eq!(Balances::free_balance(1337), 0); +// assert_eq!(Balances::reserved_balance(1337), 60); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_decrease_balance_at_most_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!(>::balance(&1337), 100); + +// assert_eq!( +// >::decrease_balance_at_most(&1337, 101), +// 100 +// ); +// assert_eq!(>::balance(&1337), 0); + +// assert_ok!(>::set_balance(&1337, 100)); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 100), +// 100 +// ); +// assert_eq!(>::balance(&1337), 0); + +// // free: 40, reserved: 60 +// assert_ok!(>::set_balance(&1337, 100)); +// assert_ok!(Balances::reserve(&1337, 60)); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 0), +// 0 +// ); +// assert_eq!(Balances::free_balance(1337) , 40); +// assert_eq!(Balances::reserved_balance(1337), 60); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 10), +// 10 +// ); +// assert_eq!(Balances::free_balance(1337), 30); +// assert_eq!( +// >::decrease_balance_at_most(&1337, 200), +// 30 +// ); +// assert_eq!(>::balance(&1337), 60); +// assert_eq!(Balances::free_balance(1337), 0); +// assert_eq!(Balances::reserved_balance(1337), 60); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_increase_balance_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_noop!( +// >::increase_balance(&1337, 0), +// TokenError::BelowMinimum +// ); +// assert_eq!( +// >::increase_balance(&1337, 1), +// Ok(1) +// ); +// assert_noop!( +// >::increase_balance(&1337, u64::MAX), +// ArithmeticError::Overflow +// ); +// }); +// } + +// #[test] +// fn fungible_unbalanced_trait_increase_balance_at_most_works() { +// <$ext_builder>::default().build().execute_with(|| { +// assert_eq!( +// >::increase_balance_at_most(&1337, 0), +// 0 +// ); +// assert_eq!( +// >::increase_balance_at_most(&1337, 1), +// 1 +// ); +// assert_eq!( +// >::increase_balance_at_most(&1337, u64::MAX), +// u64::MAX - 1 +// ); +// }); +// } +// } +// } diff --git a/pallets/native-barrier/src/tests_composite.rs b/pallets/native-barrier/src/tests_composite.rs new file mode 100644 index 000000000..07e3232fb --- /dev/null +++ b/pallets/native-barrier/src/tests_composite.rs @@ -0,0 +1,149 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2018-2022 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 + +// #![cfg(test)] + +// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; +// use frame_support::{ +// dispatch::DispatchInfo, +// parameter_types, +// traits::{ConstU32, ConstU64, ConstU8}, +// weights::{IdentityFee, Weight}, +// }; +// use pallet_transaction_payment::CurrencyAdapter; +// use sp_core::H256; +// use sp_io; +// use sp_runtime::{testing::Header, traits::IdentityLookup}; +// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +// type Block = frame_system::mocking::MockBlock; + +// frame_support::construct_runtime!( +// pub enum Test where +// Block = Block, +// NodeBlock = Block, +// UncheckedExtrinsic = UncheckedExtrinsic, +// { +// System: frame_system::{Pallet, Call, Config, Storage, Event}, +// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, +// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, +// } +// ); + +// parameter_types! { +// pub BlockWeights: frame_system::limits::BlockWeights = +// frame_system::limits::BlockWeights::simple_max( +// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), +// ); +// pub static ExistentialDeposit: u64 = 0; +// } +// impl frame_system::Config for Test { +// type BaseCallFilter = frame_support::traits::Everything; +// type BlockWeights = BlockWeights; +// type BlockLength = (); +// type DbWeight = (); +// type RuntimeOrigin = RuntimeOrigin; +// type Index = u64; +// type BlockNumber = u64; +// type RuntimeCall = RuntimeCall; +// type Hash = H256; +// type Hashing = ::sp_runtime::traits::BlakeTwo256; +// type AccountId = u64; +// type Lookup = IdentityLookup; +// type Header = Header; +// type RuntimeEvent = RuntimeEvent; +// type BlockHashCount = ConstU64<250>; +// type Version = (); +// type PalletInfo = PalletInfo; +// type AccountData = super::AccountData; +// type OnNewAccount = (); +// type OnKilledAccount = (); +// type SystemWeightInfo = (); +// type SS58Prefix = (); +// type OnSetCode = (); +// type MaxConsumers = frame_support::traits::ConstU32<16>; +// } + +// impl pallet_transaction_payment::Config for Test { +// type RuntimeEvent = RuntimeEvent; +// type OnChargeTransaction = CurrencyAdapter, ()>; +// type OperationalFeeMultiplier = ConstU8<5>; +// type WeightToFee = IdentityFee; +// type LengthToFee = IdentityFee; +// type FeeMultiplierUpdate = (); +// } + +// impl Config for Test { +// type Balance = u64; +// type DustRemoval = (); +// type RuntimeEvent = RuntimeEvent; +// type ExistentialDeposit = ExistentialDeposit; +// type AccountStore = frame_system::Pallet; +// type MaxLocks = (); +// type MaxReserves = ConstU32<2>; +// type ReserveIdentifier = [u8; 8]; +// type WeightInfo = (); +// } + +// pub struct ExtBuilder { +// existential_deposit: u64, +// monied: bool, +// } +// impl Default for ExtBuilder { +// fn default() -> Self { +// Self { existential_deposit: 1, monied: false } +// } +// } +// impl ExtBuilder { +// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { +// self.existential_deposit = existential_deposit; +// self +// } +// pub fn monied(mut self, monied: bool) -> Self { +// self.monied = monied; +// self +// } +// pub fn set_associated_consts(&self) { +// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); +// } +// pub fn build(self) -> sp_io::TestExternalities { +// self.set_associated_consts(); +// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); +// pallet_balances::GenesisConfig:: { +// balances: if self.monied { +// vec![ +// (1, 10 * self.existential_deposit), +// (2, 20 * self.existential_deposit), +// (3, 30 * self.existential_deposit), +// (4, 40 * self.existential_deposit), +// (12, 10 * self.existential_deposit), +// ] +// } else { +// vec![] +// }, +// } +// .assimilate_storage(&mut t) +// .unwrap(); + +// let mut ext = sp_io::TestExternalities::new(t); +// ext.execute_with(|| System::set_block_number(1)); +// ext +// } +// } + +// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } diff --git a/pallets/native-barrier/src/tests_local.rs b/pallets/native-barrier/src/tests_local.rs new file mode 100644 index 000000000..4f2cd2483 --- /dev/null +++ b/pallets/native-barrier/src/tests_local.rs @@ -0,0 +1,191 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2018-2022 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 + +// #![cfg(test)] + +// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; +// use frame_support::{ +// dispatch::DispatchInfo, +// parameter_types, +// traits::{ConstU32, ConstU64, ConstU8, StorageMapShim}, +// weights::{IdentityFee, Weight}, +// }; +// use pallet_transaction_payment::CurrencyAdapter; +// use sp_core::H256; +// use sp_io; +// use sp_runtime::{testing::Header, traits::IdentityLookup}; + +// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +// type Block = frame_system::mocking::MockBlock; + +// frame_support::construct_runtime!( +// pub struct Test where +// Block = Block, +// NodeBlock = Block, +// UncheckedExtrinsic = UncheckedExtrinsic, +// { +// System: frame_system::{Pallet, Call, Config, Storage, Event}, +// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, +// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, +// } +// ); + +// parameter_types! { +// pub BlockWeights: frame_system::limits::BlockWeights = +// frame_system::limits::BlockWeights::simple_max( +// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), +// ); +// pub static ExistentialDeposit: u64 = 0; +// } +// impl frame_system::Config for Test { +// type BaseCallFilter = frame_support::traits::Everything; +// type BlockWeights = BlockWeights; +// type BlockLength = (); +// type DbWeight = (); +// type RuntimeOrigin = RuntimeOrigin; +// type Index = u64; +// type BlockNumber = u64; +// type RuntimeCall = RuntimeCall; +// type Hash = H256; +// type Hashing = ::sp_runtime::traits::BlakeTwo256; +// type AccountId = u64; +// type Lookup = IdentityLookup; +// type Header = Header; +// type RuntimeEvent = RuntimeEvent; +// type BlockHashCount = ConstU64<250>; +// type Version = (); +// type PalletInfo = PalletInfo; +// type AccountData = (); +// type OnNewAccount = (); +// type OnKilledAccount = (); +// type SystemWeightInfo = (); +// type SS58Prefix = (); +// type OnSetCode = (); +// type MaxConsumers = frame_support::traits::ConstU32<16>; +// } + +// impl pallet_transaction_payment::Config for Test { +// type RuntimeEvent = RuntimeEvent; +// type OnChargeTransaction = CurrencyAdapter, ()>; +// type OperationalFeeMultiplier = ConstU8<5>; +// type WeightToFee = IdentityFee; +// type LengthToFee = IdentityFee; +// type FeeMultiplierUpdate = (); +// } + +// impl Config for Test { +// type Balance = u64; +// type DustRemoval = (); +// type RuntimeEvent = RuntimeEvent; +// type ExistentialDeposit = ExistentialDeposit; +// type AccountStore = +// StorageMapShim, system::Provider, u64, super::AccountData>; +// type MaxLocks = ConstU32<50>; +// type MaxReserves = ConstU32<2>; +// type ReserveIdentifier = [u8; 8]; +// type WeightInfo = (); +// } + +// pub struct ExtBuilder { +// existential_deposit: u64, +// monied: bool, +// } +// impl Default for ExtBuilder { +// fn default() -> Self { +// Self { existential_deposit: 1, monied: false } +// } +// } +// impl ExtBuilder { +// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { +// self.existential_deposit = existential_deposit; +// self +// } +// pub fn monied(mut self, monied: bool) -> Self { +// self.monied = monied; +// if self.existential_deposit == 0 { +// self.existential_deposit = 1; +// } +// self +// } +// pub fn set_associated_consts(&self) { +// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); +// } +// pub fn build(self) -> sp_io::TestExternalities { +// self.set_associated_consts(); +// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); +// pallet_balances::GenesisConfig:: { +// balances: if self.monied { +// vec![ +// (1, 10 * self.existential_deposit), +// (2, 20 * self.existential_deposit), +// (3, 30 * self.existential_deposit), +// (4, 40 * self.existential_deposit), +// (12, 10 * self.existential_deposit), +// ] +// } else { +// vec![] +// }, +// } +// .assimilate_storage(&mut t) +// .unwrap(); + +// let mut ext = sp_io::TestExternalities::new(t); +// ext.execute_with(|| System::set_block_number(1)); +// ext +// } +// } + +// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } + +// #[test] +// fn emit_events_with_no_existential_deposit_suicide_with_dust() { +// ::default().existential_deposit(2).build().execute_with(|| { +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), +// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), +// ] +// ); + +// let res = Balances::slash(&1, 98); +// assert_eq!(res, (NegativeImbalance::new(98), 0)); + +// // no events +// assert_eq!( +// events(), +// [RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 98 })] +// ); + +// let res = Balances::slash(&1, 1); +// assert_eq!(res, (NegativeImbalance::new(1), 0)); + +// assert_eq!( +// events(), +// [ +// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), +// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 1 }), +// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }) +// ] +// ); +// }); +// } diff --git a/pallets/native-barrier/src/tests_reentrancy.rs b/pallets/native-barrier/src/tests_reentrancy.rs new file mode 100644 index 000000000..61814e598 --- /dev/null +++ b/pallets/native-barrier/src/tests_reentrancy.rs @@ -0,0 +1,264 @@ +// // This file is part of Substrate. + +// // Copyright (C) 2018-2022 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 setup for potential reentracy and lost updates of nested mutations. + +// #![cfg(test)] + +// use crate::{self as pallet_balances, Config}; +// use frame_support::{ +// parameter_types, +// traits::{ConstU32, ConstU64, StorageMapShim}, +// }; +// use sp_core::H256; +// use sp_io; +// use sp_runtime::{testing::Header, traits::IdentityLookup}; + +// use crate::*; +// use frame_support::{ +// assert_ok, +// traits::{Currency, ReservableCurrency}, +// }; +// use frame_system::RawOrigin; + +// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +// type Block = frame_system::mocking::MockBlock; + +// frame_support::construct_runtime!( +// pub enum Test where +// Block = Block, +// NodeBlock = Block, +// UncheckedExtrinsic = UncheckedExtrinsic, +// { +// System: frame_system::{Pallet, Call, Config, Storage, Event}, +// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, +// } +// ); + +// parameter_types! { +// pub BlockWeights: frame_system::limits::BlockWeights = +// frame_system::limits::BlockWeights::simple_max( +// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), +// ); +// pub static ExistentialDeposit: u64 = 0; +// } +// impl frame_system::Config for Test { +// type BaseCallFilter = frame_support::traits::Everything; +// type BlockWeights = BlockWeights; +// type BlockLength = (); +// type DbWeight = (); +// type RuntimeOrigin = RuntimeOrigin; +// type Index = u64; +// type BlockNumber = u64; +// type RuntimeCall = RuntimeCall; +// type Hash = H256; +// type Hashing = ::sp_runtime::traits::BlakeTwo256; +// type AccountId = u64; +// type Lookup = IdentityLookup; +// type Header = Header; +// type RuntimeEvent = RuntimeEvent; +// type BlockHashCount = ConstU64<250>; +// type Version = (); +// type PalletInfo = PalletInfo; +// type AccountData = (); +// type OnNewAccount = (); +// type OnKilledAccount = (); +// type SystemWeightInfo = (); +// type SS58Prefix = (); +// type OnSetCode = (); +// type MaxConsumers = frame_support::traits::ConstU32<16>; +// } + +// pub struct OnDustRemoval; +// impl OnUnbalanced> for OnDustRemoval { +// fn on_nonzero_unbalanced(amount: NegativeImbalance) { +// assert_ok!(Balances::resolve_into_existing(&1, amount)); +// } +// } + +// impl Config for Test { +// type Balance = u64; +// type DustRemoval = OnDustRemoval; +// type RuntimeEvent = RuntimeEvent; +// type ExistentialDeposit = ExistentialDeposit; +// type AccountStore = +// StorageMapShim, system::Provider, u64, super::AccountData>; +// type MaxLocks = ConstU32<50>; +// type MaxReserves = ConstU32<2>; +// type ReserveIdentifier = [u8; 8]; +// type WeightInfo = (); +// } + +// pub struct ExtBuilder { +// existential_deposit: u64, +// } +// impl Default for ExtBuilder { +// fn default() -> Self { +// Self { existential_deposit: 1 } +// } +// } +// impl ExtBuilder { +// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { +// self.existential_deposit = existential_deposit; +// self +// } + +// pub fn set_associated_consts(&self) { +// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); +// } + +// pub fn build(self) -> sp_io::TestExternalities { +// self.set_associated_consts(); +// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); +// pallet_balances::GenesisConfig:: { balances: vec![] } +// .assimilate_storage(&mut t) +// .unwrap(); +// let mut ext = sp_io::TestExternalities::new(t); +// ext.execute_with(|| System::set_block_number(1)); +// ext +// } +// } + +// #[test] +// fn transfer_dust_removal_tst1_should_work() { +// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { +// // Verification of reentrancy in dust removal +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + +// // In this transaction, account 2 free balance +// // drops below existential balance +// // and dust balance is removed from account 2 +// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 3, 450)); + +// // As expected dust balance is removed. +// assert_eq!(Balances::free_balance(&2), 0); + +// // As expected beneficiary account 3 +// // received the transfered fund. +// assert_eq!(Balances::free_balance(&3), 450); + +// // Dust balance is deposited to account 1 +// // during the process of dust removal. +// assert_eq!(Balances::free_balance(&1), 1050); + +// // Verify the events +// assert_eq!(System::events().len(), 12); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { +// from: 2, +// to: 3, +// amount: 450, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { +// account: 2, +// amount: 50, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { +// who: 1, +// amount: 50, +// })); +// }); +// } + +// #[test] +// fn transfer_dust_removal_tst2_should_work() { +// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { +// // Verification of reentrancy in dust removal +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + +// // In this transaction, account 2 free balance +// // drops below existential balance +// // and dust balance is removed from account 2 +// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 1, 450)); + +// // As expected dust balance is removed. +// assert_eq!(Balances::free_balance(&2), 0); + +// // Dust balance is deposited to account 1 +// // during the process of dust removal. +// assert_eq!(Balances::free_balance(&1), 1500); + +// // Verify the events +// assert_eq!(System::events().len(), 10); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { +// from: 2, +// to: 1, +// amount: 450, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { +// account: 2, +// amount: 50, +// })); +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { +// who: 1, +// amount: 50, +// })); +// }); +// } + +// #[test] +// fn repatriating_reserved_balance_dust_removal_should_work() { +// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { +// // Verification of reentrancy in dust removal +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); +// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + +// // Reserve a value on account 2, +// // Such that free balance is lower than +// // Exestintial deposit. +// assert_ok!(Balances::reserve(&2, 450)); + +// // Transfer of reserved fund from slashed account 2 to +// // beneficiary account 1 +// assert_ok!(Balances::repatriate_reserved(&2, &1, 450, Status::Free), 0); + +// // Since free balance of account 2 is lower than +// // existential deposit, dust amount is +// // removed from the account 2 +// assert_eq!(Balances::reserved_balance(2), 0); +// assert_eq!(Balances::free_balance(2), 0); + +// // account 1 is credited with reserved amount +// // together with dust balance during dust +// // removal. +// assert_eq!(Balances::reserved_balance(1), 0); +// assert_eq!(Balances::free_balance(1), 1500); + +// // Verify the events +// assert_eq!(System::events().len(), 11); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { +// from: 2, +// to: 1, +// amount: 450, +// destination_status: Status::Free, +// })); + +// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { +// account: 2, +// amount: 50, +// })); + +// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { +// who: 1, +// amount: 50, +// })); +// }); +// } diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs new file mode 100644 index 000000000..6324745fd --- /dev/null +++ b/pallets/native-barrier/src/weights.rs @@ -0,0 +1,164 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 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 pallet_balances +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-11-07, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bm2`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/substrate +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/balances/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_balances. +pub trait WeightInfo { + fn transfer() -> Weight; + fn transfer_keep_alive() -> Weight; + fn set_balance_creating() -> Weight; + fn set_balance_killing() -> Weight; + fn force_transfer() -> Weight; + fn transfer_all() -> Weight; + fn force_unreserve() -> Weight; +} + +/// Weights for pallet_balances using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: System Account (r:1 w:1) + fn transfer() -> Weight { + // Minimum execution time: 48_134 nanoseconds. + Weight::from_ref_time(48_811_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_keep_alive() -> Weight { + // Minimum execution time: 36_586 nanoseconds. + Weight::from_ref_time(36_966_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_creating() -> Weight { + // Minimum execution time: 28_486 nanoseconds. + Weight::from_ref_time(28_940_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_killing() -> Weight { + // Minimum execution time: 31_225 nanoseconds. + Weight::from_ref_time(31_946_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:2 w:2) + fn force_transfer() -> Weight { + // Minimum execution time: 47_347 nanoseconds. + Weight::from_ref_time(48_005_000 as u64) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(2 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_all() -> Weight { + // Minimum execution time: 41_668 nanoseconds. + Weight::from_ref_time(42_232_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_unreserve() -> Weight { + // Minimum execution time: 23_741 nanoseconds. + Weight::from_ref_time(24_073_000 as u64) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: System Account (r:1 w:1) + fn transfer() -> Weight { + // Minimum execution time: 48_134 nanoseconds. + Weight::from_ref_time(48_811_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_keep_alive() -> Weight { + // Minimum execution time: 36_586 nanoseconds. + Weight::from_ref_time(36_966_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_creating() -> Weight { + // Minimum execution time: 28_486 nanoseconds. + Weight::from_ref_time(28_940_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn set_balance_killing() -> Weight { + // Minimum execution time: 31_225 nanoseconds. + Weight::from_ref_time(31_946_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:2 w:2) + fn force_transfer() -> Weight { + // Minimum execution time: 47_347 nanoseconds. + Weight::from_ref_time(48_005_000 as u64) + .saturating_add(RocksDbWeight::get().reads(2 as u64)) + .saturating_add(RocksDbWeight::get().writes(2 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_all() -> Weight { + // Minimum execution time: 41_668 nanoseconds. + Weight::from_ref_time(42_232_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_unreserve() -> Weight { + // Minimum execution time: 23_741 nanoseconds. + Weight::from_ref_time(24_073_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } +} From 685004f98429fe399790ad75135695950c5d8c75 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 14 Aug 2023 11:00:54 +0300 Subject: [PATCH 05/69] Split to native-barrier pallet. Integrate into pallet-balances. Per day limit without skipping days Signed-off-by: Georgi Zlatarev --- Cargo.lock | 3 + pallets/balances/Cargo.toml | 4 +- pallets/balances/src/lib.rs | 100 ++++++++++---------- pallets/native-barrier/src/lib.rs | 146 ++++++++++++++---------------- runtime/calamari/Cargo.toml | 2 + runtime/calamari/src/lib.rs | 9 ++ runtime/manta/Cargo.toml | 2 + runtime/manta/src/lib.rs | 9 ++ 8 files changed, 148 insertions(+), 127 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b094fbcb..b904a7ea8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1142,6 +1142,7 @@ dependencies = [ "pallet-membership", "pallet-multisig", "pallet-name-service", + "pallet-native-barrier", "pallet-parachain-staking", "pallet-preimage", "pallet-randomness", @@ -5557,6 +5558,7 @@ dependencies = [ "pallet-membership", "pallet-multisig", "pallet-name-service", + "pallet-native-barrier", "pallet-parachain-staking", "pallet-preimage", "pallet-randomness", @@ -6664,6 +6666,7 @@ dependencies = [ "frame-support", "frame-system", "log", + "pallet-native-barrier", "pallet-transaction-payment", "parity-scale-codec", "scale-info", diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index a546ce20c..0a5d34622 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -22,7 +22,7 @@ frame-system = { git = 'https://github.com/paritytech/substrate.git', default-fe sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -#pallet-native-barrier = { path = '../native-barrier' } +pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } @@ -40,7 +40,7 @@ std = [ "scale-info/std", "sp-runtime/std", "sp-std/std", - #"pallet-native-barrier/std" + "pallet-native-barrier/std" ] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index afa18ba21..b7b5e1f18 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -202,6 +202,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; + use pallet_native_barrier::NativeBarrier; #[pallet::config] pub trait Config: frame_system::Config { @@ -249,6 +250,9 @@ pub mod pallet { /// Timestamp provider type UnixTime: UnixTime; + + /// Timestamp provider + type NativeBarrierType: NativeBarrier; } /// The current storage version. @@ -296,8 +300,8 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - //>::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; - Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + ::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + // Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; >::transfer( &transactor, &dest, @@ -408,7 +412,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + //Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; >::transfer(&transactor, &dest, value, KeepAlive)?; Ok(().into()) } @@ -442,7 +446,7 @@ pub mod pallet { let reducible_balance = Self::reducible_balance(&transactor, keep_alive); let dest = T::Lookup::lookup(dest)?; let keep_alive = if keep_alive { KeepAlive } else { AllowDeath }; - Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, reducible_balance)?; + //Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, reducible_balance)?; >::transfer(&transactor, &dest, reducible_balance, keep_alive)?; Ok(()) } @@ -847,50 +851,50 @@ impl, I: 'static> Drop for DustCleaner { const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day impl, I: 'static> Pallet { - fn ensure_xcm_transfer_limit_not_exceeded( - account_id: &T::AccountId, - amount: T::Balance, - ) -> DispatchResult { - // The address is not in the barrier list so we don't care about it - if >::get(account_id) == None { - return Ok(()); - } - - if let Some(transfer_limit) = >::get() { - let now = T::UnixTime::now().as_secs(); - let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; - let (mut transferred, last_transfer) = >::get(account_id) - .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; - - if last_transfer < current_period { - transferred = Default::default(); - >::insert(account_id, (transferred, now)); - }; - - ensure!( - transferred + amount <= transfer_limit, - Error::::XcmTransfersLimitExceeded - ); - - Self::update_xcm_native_transfers(account_id, amount) - } - - Ok(()) - } - - fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { - if >::get().is_some() { - >::mutate_exists(account_id, |maybe_transfer| { - match maybe_transfer { - Some((current_amount, last_transfer)) => { - *current_amount = *current_amount + amount; - *last_transfer = T::UnixTime::now().as_secs(); - } - None => {} - } - }); - } - } + // fn ensure_xcm_transfer_limit_not_exceeded( + // account_id: &T::AccountId, + // amount: T::Balance, + // ) -> DispatchResult { + // // The address is not in the barrier list so we don't care about it + // if >::get(account_id) == None { + // return Ok(()); + // } + + // if let Some(transfer_limit) = >::get() { + // let now = T::UnixTime::now().as_secs(); + // let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; + // let (mut transferred, last_transfer) = >::get(account_id) + // .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + + // if last_transfer < current_period { + // transferred = Default::default(); + // >::insert(account_id, (transferred, now)); + // }; + + // ensure!( + // transferred + amount <= transfer_limit, + // Error::::XcmTransfersLimitExceeded + // ); + + // Self::update_xcm_native_transfers(account_id, amount) + // } + + // Ok(()) + // } + + // fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { + // if >::get().is_some() { + // >::mutate_exists(account_id, |maybe_transfer| { + // match maybe_transfer { + // Some((current_amount, last_transfer)) => { + // *current_amount = *current_amount + amount; + // *last_transfer = T::UnixTime::now().as_secs(); + // } + // None => {} + // } + // }); + // } + // } /// Get the free balance of an account. pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index aebfb4b1b..5f9a5d60e 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -180,7 +180,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; #[pallet::config] - pub trait Config: frame_system::Config { + pub trait Config: frame_system::Config { /// The balance of an account. type Balance: Parameter + Member @@ -195,8 +195,7 @@ pub mod pallet { + FixedPointOperand; /// The overarching event type. - type RuntimeEvent: From> - + IsType<::RuntimeEvent>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -212,10 +211,10 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] #[pallet::storage_version(STORAGE_VERSION)] - pub struct Pallet(PhantomData<(T, I)>); + pub struct Pallet(PhantomData<(T)>); #[pallet::call] - impl, I: 'static> Pallet { + impl Pallet { /// Transfer the entire transferable balance from the caller account. /// /// NOTE: This function only attempts to transfer _transferable_ balances. This means that @@ -241,20 +240,20 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; // todo: check if account exists ? - >::insert(account, ()); + >::insert(account, ()); Ok(()) } } #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event, I: 'static = ()> { + pub enum Event { /// An account was created with some free balance. Endowed, } #[pallet::error] - pub enum Error { + pub enum Error { /// XcmTransfersLimitExceeded, /// @@ -262,25 +261,31 @@ pub mod pallet { } /// Stores amount of native asset XCM transfers and timestamp of last transfer #[pallet::storage] - pub type XcmNativeTransfers, I: 'static = ()> = + pub type XcmNativeTransfers = StorageMap<_, Blake2_128Concat, T::AccountId, (T::Balance, u64), OptionQuery>; /// Stores limit value #[pallet::storage] - pub type DailyXcmLimit, I: 'static = ()> = - StorageValue<_, T::Balance, OptionQuery>; + pub type DailyXcmLimit = StorageValue<_, T::Balance, OptionQuery>; #[pallet::storage] - pub type XcmBarrierList, I: 'static = ()> = - StorageMap<_, Identity, T::AccountId, (), OptionQuery>; + pub type XcmBarrierList = StorageMap<_, Identity, T::AccountId, (), OptionQuery>; + + #[pallet::storage] + pub type RemainingXcmLimit = + StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; + + /// Stores limit value + #[pallet::storage] + pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; #[pallet::genesis_config] - pub struct GenesisConfig, I: 'static = ()> { + pub struct GenesisConfig { pub balances: Vec<(T::AccountId, T::Balance)>, } #[cfg(feature = "std")] - impl, I: 'static> Default for GenesisConfig { + impl Default for GenesisConfig { fn default() -> Self { Self { balances: Default::default(), @@ -289,25 +294,45 @@ pub mod pallet { } #[pallet::genesis_build] - impl, I: 'static> GenesisBuild for GenesisConfig { + impl GenesisBuild for GenesisConfig { fn build(&self) {} } + + pub const STARTING_UNIX_TIME: u64 = 0; + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_n: T::BlockNumber) -> Weight { + let now = T::UnixTime::now().as_secs(); + let days_since_start = (now - STARTING_UNIX_TIME) / (24 * 60 * 60); + + // You might store the last day processed in storage to avoid re-processing the same day. + let last_day_processed = >::get().unwrap_or(0); + + if days_since_start > last_day_processed { + Self::reset_remaining_xcm_limit(); + >::put(days_since_start); + } + + //T::WeightInfo::on_initialize() + Weight::from_ref_time(0) + } + } } #[cfg(feature = "std")] -impl, I: 'static> GenesisConfig { +impl GenesisConfig { /// Direct implementation of `GenesisBuild::build_storage`. /// /// Kept in order not to break dependency. pub fn build_storage(&self) -> Result { - >::build_storage(self) + >::build_storage(self) } /// Direct implementation of `GenesisBuild::assimilate_storage`. /// /// Kept in order not to break dependency. pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { - >::assimilate_storage(self, storage) + >::assimilate_storage(self, storage) } } @@ -321,30 +346,30 @@ pub trait NativeBarrier { ) -> DispatchResult; } -impl, I: 'static> NativeBarrier for Pallet { +impl NativeBarrier for Pallet { fn ensure_xcm_transfer_limit_not_exceeded( account_id: &T::AccountId, amount: T::Balance, ) -> DispatchResult { // The address is not in the barrier list so we don't care about it - if >::get(account_id) == None { + if >::get(account_id) == None { return Ok(()); } - if let Some(transfer_limit) = >::get() { + if let Some(transfer_limit) = >::get() { let now = T::UnixTime::now().as_secs(); let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; - let (mut transferred, last_transfer) = >::get(account_id) - .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + let (mut transferred, last_transfer) = >::get(account_id) + .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; if last_transfer < current_period { transferred = Default::default(); - >::insert(account_id, (transferred, now)); + >::insert(account_id, (transferred, now)); }; ensure!( transferred + amount <= transfer_limit, - Error::::XcmTransfersLimitExceeded + Error::::XcmTransfersLimitExceeded ); Self::update_xcm_native_transfers(account_id, amount) @@ -354,63 +379,30 @@ impl, I: 'static> NativeBarrier for Palle } fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { - if >::get().is_some() { - >::mutate_exists(account_id, |maybe_transfer| { - match maybe_transfer { + if >::get().is_some() { + >::mutate_exists( + account_id, + |maybe_transfer| match maybe_transfer { Some((current_amount, last_transfer)) => { *current_amount = *current_amount + amount; *last_transfer = T::UnixTime::now().as_secs(); } None => {} - } - }); + }, + ); } } } -// impl, I: 'static> Pallet { -// // fn ensure_xcm_transfer_limit_not_exceeded( -// // account_id: &T::AccountId, -// // amount: T::Balance, -// // ) -> DispatchResult { -// // // The address is not in the barrier list so we don't care about it -// // if >::get(account_id) == None { -// // return Ok(()); -// // } - -// // if let Some(transfer_limit) = >::get() { -// // let now = T::UnixTime::now().as_secs(); -// // let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; -// // let (mut transferred, last_transfer) = >::get(account_id) -// // .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; - -// // if last_transfer < current_period { -// // transferred = Default::default(); -// // >::insert(account_id, (transferred, now)); -// // }; - -// // ensure!( -// // transferred + amount <= transfer_limit, -// // Error::::XcmTransfersLimitExceeded -// // ); - -// // Self::update_xcm_native_transfers(account_id, amount) -// // } - -// // Ok(()) -// // } - -// // fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { -// // if >::get().is_some() { -// // >::mutate_exists(account_id, |maybe_transfer| { -// // match maybe_transfer { -// // Some((current_amount, last_transfer)) => { -// // *current_amount = *current_amount + amount; -// // *last_transfer = T::UnixTime::now().as_secs(); -// // } -// // None => {} -// // } -// // }); -// // } -// // } -// } +impl Pallet { + fn reset_remaining_xcm_limit() { + if let Some(daily_limit) = >::get() { + for (account_id, _) in XcmBarrierList::::iter() { + let mut remaining_limit = + >::get(&account_id).unwrap_or(daily_limit); + remaining_limit += daily_limit; + >::insert(&account_id, remaining_limit); + } + } + } +} diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 46f478bd2..a1dc09cda 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -105,6 +105,7 @@ pallet-randomness = { path = '../../pallets/randomness', default-features = fals pallet-tx-pause = { path = '../../pallets/tx-pause', default-features = false } runtime-common = { path = '../common', default-features = false } session-key-primitives = { path = '../../primitives/session-keys', default-features = false } +pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } # Third party (vendored) dependencies orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } @@ -288,6 +289,7 @@ std = [ 'xcm/std', 'xcm-builder/std', 'xcm-executor/std', + 'pallet-native-barrier/std', 'polkadot-primitives/std', 'manta-collator-selection/std', 'calamari-vesting/std', diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index c9f4f11e4..4f855d7f1 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -459,6 +459,14 @@ impl pallet_balances::Config for Runtime { type AccountStore = frame_system::Pallet; type WeightInfo = weights::pallet_balances::SubstrateWeight; type UnixTime = Timestamp; + type NativeBarrierType = NativeBarrier; +} + +impl pallet_native_barrier::Config for Runtime { + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type UnixTime = Timestamp; + type WeightInfo = (); } parameter_types! { @@ -968,6 +976,7 @@ construct_runtime!( CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 33, XTokens: orml_xtokens::{Pallet, Call, Event, Storage} = 34, + NativeBarrier: pallet_native_barrier::{Pallet, Call, Event, Storage} = 35, // Handy utilities. Utility: pallet_utility::{Pallet, Call, Event} = 40, diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index c68884ef5..e177851db 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -107,6 +107,7 @@ pallet-randomness = { path = '../../pallets/randomness', default-features = fals pallet-tx-pause = { path = '../../pallets/tx-pause', default-features = false } runtime-common = { path = '../common', default-features = false } session-key-primitives = { path = '../../primitives/session-keys', default-features = false } +pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } [dev-dependencies] csv = "1.2.1" @@ -285,6 +286,7 @@ std = [ "zenlink-protocol-runtime-api/std", "pallet-farming/std", "pallet-farming-rpc-runtime-api/std", + "pallet-native-barrier/std" ] # A feature that should be enabled when the runtime should be build for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 38d5bc7e1..1ea98b440 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -448,6 +448,14 @@ impl pallet_balances::Config for Runtime { type AccountStore = frame_system::Pallet; type WeightInfo = weights::pallet_balances::SubstrateWeight; type UnixTime = Timestamp; + type NativeBarrierType = NativeBarrier; +} + +impl pallet_native_barrier::Config for Runtime { + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type UnixTime = Timestamp; + type WeightInfo = (); } parameter_types! { @@ -937,6 +945,7 @@ construct_runtime!( CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 33, XTokens: orml_xtokens::{Pallet, Call, Event, Storage} = 34, + NativeBarrier: pallet_native_barrier::{Pallet, Call, Event, Storage} = 35, // Handy utilities. Utility: pallet_utility::{Pallet, Call, Event} = 40, From 2eb866062e62f81d2c868f52631e29f7e53ea528 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 14 Aug 2023 12:04:39 +0300 Subject: [PATCH 06/69] Support accumulation fo skipped days Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 54 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 5f9a5d60e..c912f49d7 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -163,16 +163,15 @@ use codec::{Codec, MaxEncodedLen}; use frame_support::traits::GenesisBuild; use frame_support::{ensure, pallet_prelude::DispatchResult, traits::UnixTime}; use frame_system as system; +pub use pallet::*; use scale_info::TypeInfo; use sp_runtime::{ traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}, - FixedPointOperand, + FixedPointOperand, Saturating, }; use sp_std::{fmt::Debug, prelude::*}; pub use weights::WeightInfo; -pub use pallet::*; - #[frame_support::pallet] pub mod pallet { use super::*; @@ -351,46 +350,53 @@ impl NativeBarrier for Pallet { account_id: &T::AccountId, amount: T::Balance, ) -> DispatchResult { - // The address is not in the barrier list so we don't care about it - if >::get(account_id) == None { - return Ok(()); - } + if let Some(transfer_limit) = DailyXcmLimit::::get() { + // The address is not in the barrier list, so we don't care about it + if >::get(account_id).is_none() { + return Ok(()); + } - if let Some(transfer_limit) = >::get() { let now = T::UnixTime::now().as_secs(); let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; - let (mut transferred, last_transfer) = >::get(account_id) + let (mut transferred, last_transfer) = XcmNativeTransfers::::get(account_id) .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + let remaining_limit = RemainingXcmLimit::::get(account_id).unwrap_or(transfer_limit); if last_transfer < current_period { transferred = Default::default(); - >::insert(account_id, (transferred, now)); + XcmNativeTransfers::::insert(account_id, (transferred, now)); }; ensure!( - transferred + amount <= transfer_limit, + transferred + amount <= remaining_limit, Error::::XcmTransfersLimitExceeded ); - Self::update_xcm_native_transfers(account_id, amount) + // If the ensure didn't return an error, update the native transfers + Self::update_xcm_native_transfers(account_id, amount); } Ok(()) } fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { - if >::get().is_some() { - >::mutate_exists( - account_id, - |maybe_transfer| match maybe_transfer { - Some((current_amount, last_transfer)) => { - *current_amount = *current_amount + amount; - *last_transfer = T::UnixTime::now().as_secs(); - } - None => {} - }, - ); - } + >::mutate_exists(account_id, |maybe_transfer| match maybe_transfer { + Some((current_amount, last_transfer)) => { + *current_amount = *current_amount + amount; + *last_transfer = T::UnixTime::now().as_secs(); + } + None => {} + }); + + >::mutate_exists( + account_id, + |maybe_remainder| match maybe_remainder { + Some(remainder) => { + *remainder = remainder.saturating_sub(amount); + } + None => {} + }, + ); } } From 95f10ed8d19e7ce16c7e7d9f424020136e0ac280 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 14 Aug 2023 15:17:50 +0300 Subject: [PATCH 07/69] add to mantapya Signed-off-by: Georgi Zlatarev --- Cargo.lock | 1 + pallets/balances/src/lib.rs | 55 +++------------------------ pallets/manta-pay/Cargo.toml | 2 + pallets/manta-pay/src/lib.rs | 14 +++++++ runtime/calamari/src/assets_config.rs | 5 ++- runtime/manta/src/assets_config.rs | 5 ++- 6 files changed, 28 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b904a7ea8..b02d2948b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7074,6 +7074,7 @@ dependencies = [ "pallet-assets", "pallet-balances 4.0.0-dev", "pallet-manta-support", + "pallet-native-barrier", "pallet-tx-pause", "parity-scale-codec", "rand_chacha 0.3.1", diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index b7b5e1f18..ff7383b4d 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -301,7 +301,6 @@ pub mod pallet { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; ::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; - // Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; >::transfer( &transactor, &dest, @@ -412,7 +411,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - //Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + ::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; >::transfer(&transactor, &dest, value, KeepAlive)?; Ok(().into()) } @@ -446,7 +445,10 @@ pub mod pallet { let reducible_balance = Self::reducible_balance(&transactor, keep_alive); let dest = T::Lookup::lookup(dest)?; let keep_alive = if keep_alive { KeepAlive } else { AllowDeath }; - //Self::ensure_xcm_transfer_limit_not_exceeded(&transactor, reducible_balance)?; + ::ensure_xcm_transfer_limit_not_exceeded( + &transactor, + reducible_balance, + )?; >::transfer(&transactor, &dest, reducible_balance, keep_alive)?; Ok(()) } @@ -848,54 +850,7 @@ impl, I: 'static> Drop for DustCleaner { } } -const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day - impl, I: 'static> Pallet { - // fn ensure_xcm_transfer_limit_not_exceeded( - // account_id: &T::AccountId, - // amount: T::Balance, - // ) -> DispatchResult { - // // The address is not in the barrier list so we don't care about it - // if >::get(account_id) == None { - // return Ok(()); - // } - - // if let Some(transfer_limit) = >::get() { - // let now = T::UnixTime::now().as_secs(); - // let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; - // let (mut transferred, last_transfer) = >::get(account_id) - // .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; - - // if last_transfer < current_period { - // transferred = Default::default(); - // >::insert(account_id, (transferred, now)); - // }; - - // ensure!( - // transferred + amount <= transfer_limit, - // Error::::XcmTransfersLimitExceeded - // ); - - // Self::update_xcm_native_transfers(account_id, amount) - // } - - // Ok(()) - // } - - // fn update_xcm_native_transfers(account_id: &T::AccountId, amount: T::Balance) { - // if >::get().is_some() { - // >::mutate_exists(account_id, |maybe_transfer| { - // match maybe_transfer { - // Some((current_amount, last_transfer)) => { - // *current_amount = *current_amount + amount; - // *last_transfer = T::UnixTime::now().as_secs(); - // } - // None => {} - // } - // }); - // } - // } - /// Get the free balance of an account. pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { Self::account(who.borrow()).free diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index 58a2813a7..b47c8b1b2 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -72,6 +72,7 @@ std = [ "manta-util/std", "manta-pay/std", "manta-support/std", + "pallet-native-barrier/std" ] # Precompute Benchmark Transactions @@ -119,6 +120,7 @@ manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5 manta-primitives = { path = "../../primitives/manta", default-features = false } manta-support = { package = "pallet-manta-support", path = "../manta-support", default-features = false } manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", default-features = false } +pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] lazy_static = "1.4.0" diff --git a/pallets/manta-pay/src/lib.rs b/pallets/manta-pay/src/lib.rs index 3d748ef04..4f9e3ab42 100644 --- a/pallets/manta-pay/src/lib.rs +++ b/pallets/manta-pay/src/lib.rs @@ -118,6 +118,7 @@ pub type FungibleLedgerError = assets::FungibleLedgerError; + + type NativeBarrierType: NativeBarrier; } /// Fungible Ledger Implementation for [`Config`] @@ -225,6 +228,17 @@ pub mod pallet { Error::::ZeroTransfer ); } + + let asset_id = id_from_field(post.receiver_posts[0].utxo.public_asset.id) + .ok_or(Error::::InvalidAssetId)?; + + if asset_id == >::NativeAssetId::get() { + ::ensure_xcm_transfer_limit_not_exceeded( + &origin, + asset_value_decode(post.sources[0]), + )?; + } + Self::post_transaction(None, vec![origin], vec![], post) } diff --git a/runtime/calamari/src/assets_config.rs b/runtime/calamari/src/assets_config.rs index 37dacd9f2..ddef743b6 100644 --- a/runtime/calamari/src/assets_config.rs +++ b/runtime/calamari/src/assets_config.rs @@ -16,8 +16,8 @@ use super::{ weights, xcm_config::SelfReserve, AssetManager, Assets, Balances, - EnsureRootOrThreeFourthsCouncil, NativeTokenExistentialDeposit, Runtime, RuntimeEvent, - RuntimeOrigin, TechnicalCollective, Timestamp, KMA, + EnsureRootOrThreeFourthsCouncil, NativeBarrier, NativeTokenExistentialDeposit, Runtime, + RuntimeEvent, RuntimeOrigin, TechnicalCollective, Timestamp, KMA, }; use manta_primitives::{ @@ -195,6 +195,7 @@ impl pallet_manta_pay::Config for Runtime { type WeightInfo = weights::pallet_manta_pay::SubstrateWeight; type AssetConfig = CalamariAssetConfig; type PalletId = MantaPayPalletId; + type NativeBarrierType = NativeBarrier; } parameter_types! { diff --git a/runtime/manta/src/assets_config.rs b/runtime/manta/src/assets_config.rs index a2498b943..5b7d5ec9b 100644 --- a/runtime/manta/src/assets_config.rs +++ b/runtime/manta/src/assets_config.rs @@ -16,8 +16,8 @@ use super::{ weights, xcm_config::SelfReserve, AssetManager, Assets, Balances, CouncilCollective, - NativeTokenExistentialDeposit, Runtime, RuntimeEvent, RuntimeOrigin, TechnicalCollective, - Timestamp, MANTA, + NativeBarrier, NativeTokenExistentialDeposit, Runtime, RuntimeEvent, RuntimeOrigin, + TechnicalCollective, Timestamp, MANTA, }; use manta_primitives::{ @@ -196,6 +196,7 @@ impl pallet_manta_pay::Config for Runtime { type WeightInfo = weights::pallet_manta_pay::SubstrateWeight; type AssetConfig = MantaAssetConfig; type PalletId = MantaPayPalletId; + type NativeBarrierType = NativeBarrier; } impl pallet_manta_sbt::Config for Runtime { From 64a603eedb02b1501f31efcc013c8ec68d7f934c Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 14 Aug 2023 17:02:27 +0300 Subject: [PATCH 08/69] move to orml_traits, add to xtokens and only for native assets Signed-off-by: Georgi Zlatarev --- Cargo.lock | 61 ++++++++++++++++++++++------ pallets/asset-manager/Cargo.toml | 2 +- pallets/balances/Cargo.toml | 4 +- pallets/balances/src/lib.rs | 2 +- pallets/farming/Cargo.toml | 2 +- pallets/manta-pay/Cargo.toml | 4 +- pallets/manta-pay/src/lib.rs | 2 +- pallets/native-barrier/Cargo.toml | 3 ++ pallets/native-barrier/src/lib.rs | 18 ++++---- primitives/manta/Cargo.toml | 2 +- runtime/calamari/Cargo.toml | 4 +- runtime/calamari/src/xcm_config.rs | 19 +++++++-- runtime/common/Cargo.toml | 4 +- runtime/integration-tests/Cargo.toml | 4 +- runtime/manta/Cargo.toml | 4 +- runtime/manta/src/xcm_config.rs | 19 +++++++-- 16 files changed, 111 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b02d2948b..7b8d11a89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1121,7 +1121,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -4190,7 +4190,7 @@ dependencies = [ "manta-primitives", "manta-runtime", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -5500,7 +5500,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "smallvec", @@ -5538,7 +5538,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -6395,6 +6395,24 @@ dependencies = [ "num-traits", ] +[[package]] +name = "orml-traits" +version = "0.4.1-dev" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" +dependencies = [ + "frame-support", + "impl-trait-for-tuples", + "num-traits", + "orml-utilities 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "parity-scale-codec", + "scale-info", + "serde", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", +] + [[package]] name = "orml-traits" version = "0.4.1-dev" @@ -6403,7 +6421,7 @@ dependencies = [ "frame-support", "impl-trait-for-tuples", "num-traits", - "orml-utilities", + "orml-utilities 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "serde", @@ -6413,6 +6431,20 @@ dependencies = [ "xcm", ] +[[package]] +name = "orml-utilities" +version = "0.4.1-dev" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" +dependencies = [ + "frame-support", + "parity-scale-codec", + "scale-info", + "serde", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "orml-utilities" version = "0.4.1-dev" @@ -6430,10 +6462,10 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed87ba5bb12c756b3973b3f59a430bab22fc0cc9" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" dependencies = [ "frame-support", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "parity-scale-codec", "sp-runtime", "sp-std", @@ -6444,12 +6476,12 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed87ba5bb12c756b3973b3f59a430bab22fc0cc9" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" dependencies = [ "cumulus-primitives-core", "frame-support", "frame-system", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xcm-support", "pallet-xcm", "parity-scale-codec", @@ -6503,7 +6535,7 @@ dependencies = [ "frame-system", "log", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-assets", "pallet-balances 4.0.0-dev", "parity-scale-codec", @@ -6666,6 +6698,7 @@ dependencies = [ "frame-support", "frame-system", "log", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-native-barrier", "pallet-transaction-payment", "parity-scale-codec", @@ -6883,7 +6916,7 @@ dependencies = [ "hex-literal", "log", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.0.0-dev", @@ -7070,6 +7103,7 @@ dependencies = [ "manta-pay", "manta-primitives", "manta-util", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.0.0-dev", @@ -7230,6 +7264,7 @@ dependencies = [ "frame-support", "frame-system", "log", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-transaction-payment", "parity-scale-codec", "scale-info", @@ -10100,7 +10135,7 @@ dependencies = [ "frame-system", "lazy_static", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -15062,7 +15097,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", diff --git a/pallets/asset-manager/Cargo.toml b/pallets/asset-manager/Cargo.toml index d4b5a4c4d..d99fd432e 100644 --- a/pallets/asset-manager/Cargo.toml +++ b/pallets/asset-manager/Cargo.toml @@ -21,7 +21,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad xcm = { git = "https://github.com/paritytech/polkadot.git", default-features = false, branch = "release-v0.9.37" } # 3rd party dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index 0a5d34622..ffb144254 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -23,6 +23,7 @@ sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-feat sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } pallet-native-barrier = { path = '../native-barrier', default-features = false } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } @@ -40,7 +41,8 @@ std = [ "scale-info/std", "sp-runtime/std", "sp-std/std", - "pallet-native-barrier/std" + "pallet-native-barrier/std", + "orml-traits/std" ] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index ff7383b4d..36808e824 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -202,7 +202,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use pallet_native_barrier::NativeBarrier; + use orml_traits::xcm_transfer::NativeBarrier; #[pallet::config] pub trait Config: frame_system::Config { diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 5ac208f4c..9c8d19d24 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -24,7 +24,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37", default-features = false } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37", default-features = false } pallet-asset-manager = { path = "../asset-manager", default-features = false, optional = true } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "release-v0.9.37", default-features = false, optional = true } diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index b47c8b1b2..b0c4e9669 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -72,7 +72,8 @@ std = [ "manta-util/std", "manta-pay/std", "manta-support/std", - "pallet-native-barrier/std" + "pallet-native-barrier/std", + "orml-traits/std" ] # Precompute Benchmark Transactions @@ -121,6 +122,7 @@ manta-primitives = { path = "../../primitives/manta", default-features = false } manta-support = { package = "pallet-manta-support", path = "../manta-support", default-features = false } manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", default-features = false } pallet-native-barrier = { path = '../native-barrier', default-features = false } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] lazy_static = "1.4.0" diff --git a/pallets/manta-pay/src/lib.rs b/pallets/manta-pay/src/lib.rs index 4f9e3ab42..c777800de 100644 --- a/pallets/manta-pay/src/lib.rs +++ b/pallets/manta-pay/src/lib.rs @@ -118,7 +118,7 @@ pub type FungibleLedgerError = assets::FungibleLedgerError GenesisConfig { const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day -pub trait NativeBarrier { - fn update_xcm_native_transfers(account_id: &AccountId, amount: Balance); - fn ensure_xcm_transfer_limit_not_exceeded( - account_id: &AccountId, - amount: Balance, - ) -> DispatchResult; -} - -impl NativeBarrier for Pallet { +// pub trait NativeBarrier { +// fn update_xcm_native_transfers(account_id: &AccountId, amount: Balance); +// fn ensure_xcm_transfer_limit_not_exceeded( +// account_id: &AccountId, +// amount: Balance, +// ) -> DispatchResult; +// } + +impl orml_traits::xcm_transfer::NativeBarrier for Pallet { fn ensure_xcm_transfer_limit_not_exceeded( account_id: &T::AccountId, amount: T::Balance, diff --git a/primitives/manta/Cargo.toml b/primitives/manta/Cargo.toml index 8b5b068ff..e46add363 100644 --- a/primitives/manta/Cargo.toml +++ b/primitives/manta/Cargo.toml @@ -28,7 +28,7 @@ xcm = { git = 'https://github.com/paritytech/polkadot.git', default-features = f xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "polkadot-v0.9.37", default-features = false } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "ghzlatarev/polkadot-v0.9.37", default-features = false } [features] default = ["std"] diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index a1dc09cda..1d85d81b6 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -108,8 +108,8 @@ session-key-primitives = { path = '../../primitives/session-keys', default-featu pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } # Third party (vendored) dependencies -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } diff --git a/runtime/calamari/src/xcm_config.rs b/runtime/calamari/src/xcm_config.rs index 0e414c51c..c989d78cb 100644 --- a/runtime/calamari/src/xcm_config.rs +++ b/runtime/calamari/src/xcm_config.rs @@ -15,9 +15,10 @@ // along with Manta. If not, see . use super::{ - assets_config::CalamariAssetConfig, AssetManager, Assets, Balances, DmpQueue, - EnsureRootOrMoreThanHalfCouncil, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, - RuntimeCall, RuntimeEvent, RuntimeOrigin, Treasury, XcmpQueue, MAXIMUM_BLOCK_WEIGHT, + assets_config::{CalamariAssetConfig, NativeAssetLocation}, + AssetManager, Assets, Balances, DmpQueue, EnsureRootOrMoreThanHalfCouncil, NativeBarrier, + ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + Treasury, XcmpQueue, MAXIMUM_BLOCK_WEIGHT, }; use codec::{Decode, Encode}; use core::marker::PhantomData; @@ -347,6 +348,17 @@ impl Contains for AssetManager { } } +impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { + fn is_native(currency_id: &CurrencyId) -> bool { + let asset_location = + CurrencyIdtoMultiLocation::>::convert( + currency_id.clone(), + ); + // todo: unwrap + asset_location == NativeAssetLocation::get().into() + } +} + // The XCM message wrapper wrapper impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -375,5 +387,6 @@ impl orml_xtokens::Config for Runtime { type MinXcmFee = AssetManager; type MultiLocationsFilter = AssetManager; type OutgoingAssetsFilter = AssetManager; + type NativeBarrierType = NativeBarrier; type ReserveProvider = AbsoluteReserveProvider; } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 17d74e937..cb3b8343b 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -56,8 +56,8 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.37" } # Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } # Self dependencies pallet-asset-manager = { path = '../../pallets/asset-manager' } diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 4f30200ac..811892523 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -52,8 +52,8 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.37" } # Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } # Self dependencies calamari-vesting = { path = '../../pallets/vesting' } diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index e177851db..957232b37 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -85,8 +85,8 @@ xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-feat xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } # Third party (vendored) dependencies -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } diff --git a/runtime/manta/src/xcm_config.rs b/runtime/manta/src/xcm_config.rs index fc63d7858..5397c169e 100644 --- a/runtime/manta/src/xcm_config.rs +++ b/runtime/manta/src/xcm_config.rs @@ -15,9 +15,10 @@ // along with Manta. If not, see . use super::{ - assets_config::MantaAssetConfig, AssetManager, Assets, Balance, Balances, DmpQueue, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - Treasury, XcmpQueue, MAXIMUM_BLOCK_WEIGHT, + assets_config::{MantaAssetConfig, NativeAssetLocation}, + AssetManager, Assets, Balance, Balances, DmpQueue, NativeBarrier, ParachainInfo, + ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Treasury, + XcmpQueue, MAXIMUM_BLOCK_WEIGHT, }; use codec::{Decode, Encode}; @@ -326,6 +327,17 @@ impl Contains for AssetManager { } } +impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { + fn is_native(currency_id: &CurrencyId) -> bool { + let asset_location = + CurrencyIdtoMultiLocation::>::convert( + currency_id.clone(), + ); + //asset_location == MultiLocation::from(NativeAssetLocation::get()) + asset_location == NativeAssetLocation::get().into() + } +} + // The XCM message wrapper wrapper impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -352,5 +364,6 @@ impl orml_xtokens::Config for Runtime { type MinXcmFee = AssetManager; type MultiLocationsFilter = AssetManager; type OutgoingAssetsFilter = AssetManager; + type NativeBarrierType = NativeBarrier; type ReserveProvider = AbsoluteReserveProvider; } From 351ef1db4571f82ee7bc0610008171d3272510b7 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 06:17:43 +0300 Subject: [PATCH 09/69] Add Here check for native assets Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 8 -------- runtime/calamari/src/xcm_config.rs | 3 +-- runtime/manta/src/xcm_config.rs | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index f857ab026..95879c1f6 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -337,14 +337,6 @@ impl GenesisConfig { const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day -// pub trait NativeBarrier { -// fn update_xcm_native_transfers(account_id: &AccountId, amount: Balance); -// fn ensure_xcm_transfer_limit_not_exceeded( -// account_id: &AccountId, -// amount: Balance, -// ) -> DispatchResult; -// } - impl orml_traits::xcm_transfer::NativeBarrier for Pallet { fn ensure_xcm_transfer_limit_not_exceeded( account_id: &T::AccountId, diff --git a/runtime/calamari/src/xcm_config.rs b/runtime/calamari/src/xcm_config.rs index c989d78cb..a8ba79d6c 100644 --- a/runtime/calamari/src/xcm_config.rs +++ b/runtime/calamari/src/xcm_config.rs @@ -354,8 +354,7 @@ impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { CurrencyIdtoMultiLocation::>::convert( currency_id.clone(), ); - // todo: unwrap - asset_location == NativeAssetLocation::get().into() + asset_location == NativeAssetLocation::get().into() || asset_location == Some(Here.into()) } } diff --git a/runtime/manta/src/xcm_config.rs b/runtime/manta/src/xcm_config.rs index 5397c169e..de4c347f8 100644 --- a/runtime/manta/src/xcm_config.rs +++ b/runtime/manta/src/xcm_config.rs @@ -334,7 +334,7 @@ impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { currency_id.clone(), ); //asset_location == MultiLocation::from(NativeAssetLocation::get()) - asset_location == NativeAssetLocation::get().into() + asset_location == NativeAssetLocation::get().into() || asset_location == Some(Here.into()) } } From 2a57473b71a0aecc0de58965c713ce5a40aba229 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 06:38:40 +0300 Subject: [PATCH 10/69] Uncomment pallet0balances tests and benchs Signed-off-by: Georgi Zlatarev --- pallets/balances/src/benchmarking.rs | 444 ++-- pallets/balances/src/lib.rs | 4 +- pallets/balances/src/migration.rs | 206 +- pallets/balances/src/tests.rs | 2826 +++++++++++----------- pallets/balances/src/tests_composite.rs | 279 +-- pallets/balances/src/tests_local.rs | 403 +-- pallets/balances/src/tests_reentrancy.rs | 541 +++-- 7 files changed, 2371 insertions(+), 2332 deletions(-) diff --git a/pallets/balances/src/benchmarking.rs b/pallets/balances/src/benchmarking.rs index 164d10d44..a310d46d7 100644 --- a/pallets/balances/src/benchmarking.rs +++ b/pallets/balances/src/benchmarking.rs @@ -1,222 +1,222 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2020-2022 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. - -// //! Balances pallet benchmarking. - -// #![cfg(feature = "runtime-benchmarks")] - -// use super::*; - -// use frame_benchmarking::{account, benchmarks_instance_pallet, whitelisted_caller}; -// use frame_system::RawOrigin; -// use sp_runtime::traits::Bounded; - -// use crate::Pallet as Balances; - -// const SEED: u32 = 0; -// // existential deposit multiplier -// const ED_MULTIPLIER: u32 = 10; - -// benchmarks_instance_pallet! { -// // Benchmark `transfer` extrinsic with the worst possible conditions: -// // * Transfer will kill the sender account. -// // * Transfer will create the recipient account. -// transfer { -// let existential_deposit = T::ExistentialDeposit::get(); -// let caller = whitelisted_caller(); - -// // Give some multiple of the existential deposit -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - -// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, -// // and reap this user. -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); -// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); -// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // Benchmark `transfer` with the best possible condition: -// // * Both accounts exist and will continue to exist. -// #[extra] -// transfer_best_case { -// let caller = whitelisted_caller(); -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - -// // Give the sender account max funds for transfer (their account will never reasonably be killed). -// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); - -// // Give the recipient account existential deposit (thus their account already exists). -// let existential_deposit = T::ExistentialDeposit::get(); -// let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); -// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert!(!Balances::::free_balance(&caller).is_zero()); -// assert!(!Balances::::free_balance(&recipient).is_zero()); -// } - -// // Benchmark `transfer_keep_alive` with the worst possible condition: -// // * The recipient account is created. -// transfer_keep_alive { -// let caller = whitelisted_caller(); -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - -// // Give the sender account max funds, thus a transfer will not kill account. -// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); -// let existential_deposit = T::ExistentialDeposit::get(); -// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert!(!Balances::::free_balance(&caller).is_zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // Benchmark `set_balance` coming from ROOT account. This always creates an account. -// set_balance_creating { -// let user: T::AccountId = account("user", 0, SEED); -// let user_lookup = T::Lookup::unlookup(user.clone()); - -// // Give the user some initial balance. -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); -// }: set_balance(RawOrigin::Root, user_lookup, balance_amount, balance_amount) -// verify { -// assert_eq!(Balances::::free_balance(&user), balance_amount); -// assert_eq!(Balances::::reserved_balance(&user), balance_amount); -// } - -// // Benchmark `set_balance` coming from ROOT account. This always kills an account. -// set_balance_killing { -// let user: T::AccountId = account("user", 0, SEED); -// let user_lookup = T::Lookup::unlookup(user.clone()); - -// // Give the user some initial balance. -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); -// }: set_balance(RawOrigin::Root, user_lookup, Zero::zero(), Zero::zero()) -// verify { -// assert!(Balances::::free_balance(&user).is_zero()); -// } - -// // Benchmark `force_transfer` extrinsic with the worst possible conditions: -// // * Transfer will kill the sender account. -// // * Transfer will create the recipient account. -// force_transfer { -// let existential_deposit = T::ExistentialDeposit::get(); -// let source: T::AccountId = account("source", 0, SEED); -// let source_lookup = T::Lookup::unlookup(source.clone()); - -// // Give some multiple of the existential deposit -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&source, balance); - -// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); -// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); -// }: force_transfer(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount) -// verify { -// assert_eq!(Balances::::free_balance(&source), Zero::zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // This benchmark performs the same operation as `transfer` in the worst case scenario, -// // but additionally introduces many new users into the storage, increasing the the merkle -// // trie and PoV size. -// #[extra] -// transfer_increasing_users { -// // 1_000 is not very much, but this upper bound can be controlled by the CLI. -// let u in 0 .. 1_000; -// let existential_deposit = T::ExistentialDeposit::get(); -// let caller = whitelisted_caller(); - -// // Give some multiple of the existential deposit -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - -// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, -// // and reap this user. -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); -// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); - -// // Create a bunch of users in storage. -// for i in 0 .. u { -// // The `account` function uses `blake2_256` to generate unique accounts, so these -// // should be quite random and evenly distributed in the trie. -// let new_user: T::AccountId = account("new_user", i, SEED); -// let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); -// } -// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // Benchmark `transfer_all` with the worst possible condition: -// // * The recipient account is created -// // * The sender is killed -// transfer_all { -// let caller = whitelisted_caller(); -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - -// // Give some multiple of the existential deposit -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); -// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, false) -// verify { -// assert!(Balances::::free_balance(&caller).is_zero()); -// assert_eq!(Balances::::free_balance(&recipient), balance); -// } - -// force_unreserve { -// let user: T::AccountId = account("user", 0, SEED); -// let user_lookup = T::Lookup::unlookup(user.clone()); - -// // Give some multiple of the existential deposit -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&user, balance); - -// // Reserve the balance -// as ReservableCurrency<_>>::reserve(&user, balance)?; -// assert_eq!(Balances::::reserved_balance(&user), balance); -// assert!(Balances::::free_balance(&user).is_zero()); - -// }: _(RawOrigin::Root, user_lookup, balance) -// verify { -// assert!(Balances::::reserved_balance(&user).is_zero()); -// assert_eq!(Balances::::free_balance(&user), balance); -// } - -// impl_benchmark_test_suite!( -// Balances, -// crate::tests_composite::ExtBuilder::default().build(), -// crate::tests_composite::Test, -// ) -// } +// This file is part of Substrate. + +// Copyright (C) 2020-2022 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. + +//! Balances pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_benchmarking::{account, benchmarks_instance_pallet, whitelisted_caller}; +use frame_system::RawOrigin; +use sp_runtime::traits::Bounded; + +use crate::Pallet as Balances; + +const SEED: u32 = 0; +// existential deposit multiplier +const ED_MULTIPLIER: u32 = 10; + +benchmarks_instance_pallet! { + // Benchmark `transfer` extrinsic with the worst possible conditions: + // * Transfer will kill the sender account. + // * Transfer will create the recipient account. + transfer { + let existential_deposit = T::ExistentialDeposit::get(); + let caller = whitelisted_caller(); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, + // and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) + verify { + assert_eq!(Balances::::free_balance(&caller), Zero::zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // Benchmark `transfer` with the best possible condition: + // * Both accounts exist and will continue to exist. + #[extra] + transfer_best_case { + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + + // Give the sender account max funds for transfer (their account will never reasonably be killed). + let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + + // Give the recipient account existential deposit (thus their account already exists). + let existential_deposit = T::ExistentialDeposit::get(); + let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); + let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) + verify { + assert!(!Balances::::free_balance(&caller).is_zero()); + assert!(!Balances::::free_balance(&recipient).is_zero()); + } + + // Benchmark `transfer_keep_alive` with the worst possible condition: + // * The recipient account is created. + transfer_keep_alive { + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + + // Give the sender account max funds, thus a transfer will not kill account. + let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + let existential_deposit = T::ExistentialDeposit::get(); + let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) + verify { + assert!(!Balances::::free_balance(&caller).is_zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // Benchmark `set_balance` coming from ROOT account. This always creates an account. + set_balance_creating { + let user: T::AccountId = account("user", 0, SEED); + let user_lookup = T::Lookup::unlookup(user.clone()); + + // Give the user some initial balance. + let existential_deposit = T::ExistentialDeposit::get(); + let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); + }: set_balance(RawOrigin::Root, user_lookup, balance_amount, balance_amount) + verify { + assert_eq!(Balances::::free_balance(&user), balance_amount); + assert_eq!(Balances::::reserved_balance(&user), balance_amount); + } + + // Benchmark `set_balance` coming from ROOT account. This always kills an account. + set_balance_killing { + let user: T::AccountId = account("user", 0, SEED); + let user_lookup = T::Lookup::unlookup(user.clone()); + + // Give the user some initial balance. + let existential_deposit = T::ExistentialDeposit::get(); + let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); + }: set_balance(RawOrigin::Root, user_lookup, Zero::zero(), Zero::zero()) + verify { + assert!(Balances::::free_balance(&user).is_zero()); + } + + // Benchmark `force_transfer` extrinsic with the worst possible conditions: + // * Transfer will kill the sender account. + // * Transfer will create the recipient account. + force_transfer { + let existential_deposit = T::ExistentialDeposit::get(); + let source: T::AccountId = account("source", 0, SEED); + let source_lookup = T::Lookup::unlookup(source.clone()); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&source, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + }: force_transfer(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount) + verify { + assert_eq!(Balances::::free_balance(&source), Zero::zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // This benchmark performs the same operation as `transfer` in the worst case scenario, + // but additionally introduces many new users into the storage, increasing the the merkle + // trie and PoV size. + #[extra] + transfer_increasing_users { + // 1_000 is not very much, but this upper bound can be controlled by the CLI. + let u in 0 .. 1_000; + let existential_deposit = T::ExistentialDeposit::get(); + let caller = whitelisted_caller(); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, + // and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + + // Create a bunch of users in storage. + for i in 0 .. u { + // The `account` function uses `blake2_256` to generate unique accounts, so these + // should be quite random and evenly distributed in the trie. + let new_user: T::AccountId = account("new_user", i, SEED); + let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); + } + }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) + verify { + assert_eq!(Balances::::free_balance(&caller), Zero::zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // Benchmark `transfer_all` with the worst possible condition: + // * The recipient account is created + // * The sender is killed + transfer_all { + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + + // Give some multiple of the existential deposit + let existential_deposit = T::ExistentialDeposit::get(); + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, false) + verify { + assert!(Balances::::free_balance(&caller).is_zero()); + assert_eq!(Balances::::free_balance(&recipient), balance); + } + + force_unreserve { + let user: T::AccountId = account("user", 0, SEED); + let user_lookup = T::Lookup::unlookup(user.clone()); + + // Give some multiple of the existential deposit + let existential_deposit = T::ExistentialDeposit::get(); + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&user, balance); + + // Reserve the balance + as ReservableCurrency<_>>::reserve(&user, balance)?; + assert_eq!(Balances::::reserved_balance(&user), balance); + assert!(Balances::::free_balance(&user).is_zero()); + + }: _(RawOrigin::Root, user_lookup, balance) + verify { + assert!(Balances::::reserved_balance(&user).is_zero()); + assert_eq!(Balances::::free_balance(&user), balance); + } + + impl_benchmark_test_suite!( + Balances, + crate::tests_composite::ExtBuilder::default().build(), + crate::tests_composite::Test, + ) +} diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 36808e824..2c910db77 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -248,10 +248,10 @@ pub mod pallet { /// The id type for named reserves. type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; - /// Timestamp provider + /// TODO: remove type UnixTime: UnixTime; - /// Timestamp provider + /// TODO: comment type NativeBarrierType: NativeBarrier; } diff --git a/pallets/balances/src/migration.rs b/pallets/balances/src/migration.rs index 6d47a16f4..713f49f61 100644 --- a/pallets/balances/src/migration.rs +++ b/pallets/balances/src/migration.rs @@ -1,103 +1,103 @@ -// // Copyright 2017-2020 Parity Technologies (UK) Ltd. -// // This file is part of Polkadot. - -// // Polkadot is free software: you can redistribute it and/or modify -// // it under the terms of the GNU General Public License as published by -// // the Free Software Foundation, either version 3 of the License, or -// // (at your option) any later version. - -// // Polkadot is distributed in the hope that it will be useful, -// // but WITHOUT ANY WARRANTY; without even the implied warranty of -// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// // GNU General Public License for more details. - -// // You should have received a copy of the GNU General Public License -// // along with Polkadot. If not, see . - -// use super::*; -// use frame_support::{ -// pallet_prelude::*, -// traits::{OnRuntimeUpgrade, PalletInfoAccess}, -// weights::Weight, -// }; - -// fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { -// let onchain_version = Pallet::::on_chain_storage_version(); - -// if onchain_version == 0 { -// let total = accounts -// .iter() -// .map(|a| Pallet::::total_balance(a)) -// .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); -// Pallet::::deactivate(total); - -// // Remove the old `StorageVersion` type. -// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( -// Pallet::::name().as_bytes(), -// "StorageVersion".as_bytes(), -// )); - -// // Set storage version to `1`. -// StorageVersion::new(1).put::>(); - -// log::info!(target: LOG_TARGET, "Storage to version 1"); -// T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) -// } else { -// log::info!( -// target: LOG_TARGET, -// "Migration did not execute. This probably should be removed" -// ); -// T::DbWeight::get().reads(1) -// } -// } - -// // NOTE: This must be used alongside the account whose balance is expected to be inactive. -// // Generally this will be used for the XCM teleport checking account. -// pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); -// impl, A: Get, I: 'static> OnRuntimeUpgrade -// for MigrateToTrackInactive -// { -// fn on_runtime_upgrade() -> Weight { -// migrate_v0_to_v1::(&[A::get()]) -// } -// } - -// // NOTE: This must be used alongside the accounts whose balance is expected to be inactive. -// // Generally this will be used for the XCM teleport checking accounts. -// pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); -// impl, A: Get>, I: 'static> OnRuntimeUpgrade -// for MigrateManyToTrackInactive -// { -// fn on_runtime_upgrade() -> Weight { -// migrate_v0_to_v1::(&A::get()) -// } -// } - -// pub struct ResetInactive(PhantomData<(T, I)>); -// impl, I: 'static> OnRuntimeUpgrade for ResetInactive { -// fn on_runtime_upgrade() -> Weight { -// let onchain_version = Pallet::::on_chain_storage_version(); - -// if onchain_version == 1 { -// // Remove the old `StorageVersion` type. -// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( -// Pallet::::name().as_bytes(), -// "StorageVersion".as_bytes(), -// )); - -// InactiveIssuance::::kill(); - -// // Set storage version to `0`. -// StorageVersion::new(0).put::>(); - -// log::info!(target: LOG_TARGET, "Storage to version 0"); -// T::DbWeight::get().reads_writes(1, 2) -// } else { -// log::info!( -// target: LOG_TARGET, -// "Migration did not execute. This probably should be removed" -// ); -// T::DbWeight::get().reads(1) -// } -// } -// } +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use super::*; +use frame_support::{ + pallet_prelude::*, + traits::{OnRuntimeUpgrade, PalletInfoAccess}, + weights::Weight, +}; + +fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { + let onchain_version = Pallet::::on_chain_storage_version(); + + if onchain_version == 0 { + let total = accounts + .iter() + .map(|a| Pallet::::total_balance(a)) + .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); + Pallet::::deactivate(total); + + // Remove the old `StorageVersion` type. + frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( + Pallet::::name().as_bytes(), + "StorageVersion".as_bytes(), + )); + + // Set storage version to `1`. + StorageVersion::new(1).put::>(); + + log::info!(target: LOG_TARGET, "Storage to version 1"); + T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) + } else { + log::info!( + target: LOG_TARGET, + "Migration did not execute. This probably should be removed" + ); + T::DbWeight::get().reads(1) + } +} + +// NOTE: This must be used alongside the account whose balance is expected to be inactive. +// Generally this will be used for the XCM teleport checking account. +pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); +impl, A: Get, I: 'static> OnRuntimeUpgrade + for MigrateToTrackInactive +{ + fn on_runtime_upgrade() -> Weight { + migrate_v0_to_v1::(&[A::get()]) + } +} + +// NOTE: This must be used alongside the accounts whose balance is expected to be inactive. +// Generally this will be used for the XCM teleport checking accounts. +pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); +impl, A: Get>, I: 'static> OnRuntimeUpgrade + for MigrateManyToTrackInactive +{ + fn on_runtime_upgrade() -> Weight { + migrate_v0_to_v1::(&A::get()) + } +} + +pub struct ResetInactive(PhantomData<(T, I)>); +impl, I: 'static> OnRuntimeUpgrade for ResetInactive { + fn on_runtime_upgrade() -> Weight { + let onchain_version = Pallet::::on_chain_storage_version(); + + if onchain_version == 1 { + // Remove the old `StorageVersion` type. + frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( + Pallet::::name().as_bytes(), + "StorageVersion".as_bytes(), + )); + + InactiveIssuance::::kill(); + + // Set storage version to `0`. + StorageVersion::new(0).put::>(); + + log::info!(target: LOG_TARGET, "Storage to version 0"); + T::DbWeight::get().reads_writes(1, 2) + } else { + log::info!( + target: LOG_TARGET, + "Migration did not execute. This probably should be removed" + ); + T::DbWeight::get().reads(1) + } + } +} diff --git a/pallets/balances/src/tests.rs b/pallets/balances/src/tests.rs index 2869b547d..433e6be71 100644 --- a/pallets/balances/src/tests.rs +++ b/pallets/balances/src/tests.rs @@ -1,1456 +1,1456 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2017-2022 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. - -// //! Macro for creating the tests for the module. - -// #![cfg(test)] - -// #[macro_export] -// macro_rules! decl_tests { -// ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { - -// use crate::*; -// use sp_runtime::{ArithmeticError, TokenError, FixedPointNumber, traits::{SignedExtension, BadOrigin}}; -// use frame_support::{ -// assert_noop, assert_storage_noop, assert_ok, assert_err, -// traits::{ -// LockableCurrency, LockIdentifier, WithdrawReasons, -// Currency, ReservableCurrency, ExistenceRequirement::AllowDeath -// } -// }; -// use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; -// use frame_system::RawOrigin; - -// const ID_1: LockIdentifier = *b"1 "; -// const ID_2: LockIdentifier = *b"2 "; - -// pub const CALL: &<$test as frame_system::Config>::RuntimeCall = -// &RuntimeCall::Balances(pallet_balances::Call::transfer { dest: 0, value: 0 }); - -// /// create a transaction info struct from weight. Handy to avoid building the whole struct. -// pub fn info_from_weight(w: Weight) -> DispatchInfo { -// DispatchInfo { weight: w, ..Default::default() } -// } - -// fn events() -> Vec { -// let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); - -// System::reset_events(); - -// evt -// } - -// #[test] -// fn basic_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// assert_eq!(Balances::free_balance(1), 10); -// Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 5, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn account_should_be_reaped() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// assert_eq!(Balances::free_balance(1), 10); -// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); -// // Check that the account is dead. -// assert!(!frame_system::Account::::contains_key(&1)); -// }); -// } - -// #[test] -// fn reap_failed_due_to_provider_and_consumer() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// // SCENARIO: only one provider and there are remaining consumers. -// assert_ok!(System::inc_consumers(&1)); -// assert!(!System::can_dec_provider(&1)); -// assert_noop!( -// >::transfer(&1, &2, 10, AllowDeath), -// Error::<$test, _>::KeepAlive -// ); -// assert!(System::account_exists(&1)); -// assert_eq!(Balances::free_balance(1), 10); - -// // SCENARIO: more than one provider, but will not kill account due to other provider. -// assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); -// assert_eq!(System::providers(&1), 2); -// assert!(System::can_dec_provider(&1)); -// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); -// assert_eq!(System::providers(&1), 1); -// assert!(System::account_exists(&1)); -// assert_eq!(Balances::free_balance(1), 0); -// }); -// } - -// #[test] -// fn partial_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn lock_removal_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); -// Balances::remove_lock(ID_1, &1); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn lock_replacement_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn double_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn combination_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); -// Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn lock_value_extension_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 3, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn lock_reasons_should_work() { -// <$ext_builder>::default() -// .existential_deposit(1) -// .monied(true) -// .build() -// .execute_with(|| { -// pallet_transaction_payment::NextFeeMultiplier::<$test>::put( -// Multiplier::saturating_from_integer(1) -// ); -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); -// assert_noop!( -// >::transfer(&1, &2, 1, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// assert_noop!( -// >::reserve(&1, 1), -// Error::<$test, _>::LiquidityRestrictions, -// ); -// assert!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(1), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// ).is_err()); -// assert_ok!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(0), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// )); - -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// assert_ok!(>::reserve(&1, 1)); -// assert!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(1), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// ).is_err()); -// assert!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(0), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// ).is_err()); -// }); -// } - -// #[test] -// fn lock_block_number_extension_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// System::set_block_number(2); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 3, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn lock_reasons_extension_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn default_indexing_on_new_accounts_should_not_work2() { -// <$ext_builder>::default() -// .existential_deposit(10) -// .monied(true) -// .build() -// .execute_with(|| { -// // account 5 should not exist -// // ext_deposit is 10, value is 9, not satisfies for ext_deposit -// assert_noop!( -// Balances::transfer(Some(1).into(), 5, 9), -// Error::<$test, _>::ExistentialDeposit, -// ); -// assert_eq!(Balances::free_balance(1), 100); -// }); -// } - -// #[test] -// fn reserved_balance_should_prevent_reclaim_count() { -// <$ext_builder>::default() -// .existential_deposit(256 * 1) -// .monied(true) -// .build() -// .execute_with(|| { -// System::inc_account_nonce(&2); -// assert_eq!(Balances::total_balance(&2), 256 * 20); - -// assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved -// assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." -// assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. -// assert_eq!(System::account_nonce(&2), 1); - -// // account 4 tries to take index 1 for account 5. -// assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); -// assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - -// assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed -// // "reserve" account reduced to 255 (below ED) so account deleted -// assert_eq!(Balances::total_balance(&2), 0); -// assert_eq!(System::account_nonce(&2), 0); // nonce zero - -// // account 4 tries to take index 1 again for account 6. -// assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); -// assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); -// }); -// } - -// #[test] -// fn reward_should_work() { -// <$ext_builder>::default().monied(true).build().execute_with(|| { -// assert_eq!(Balances::total_balance(&1), 10); -// assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 })); -// assert_eq!(Balances::total_balance(&1), 20); -// assert_eq!(>::get(), 120); -// }); -// } - -// #[test] -// fn dust_account_removal_should_work() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .monied(true) -// .build() -// .execute_with(|| { -// System::inc_account_nonce(&2); -// assert_eq!(System::account_nonce(&2), 1); -// assert_eq!(Balances::total_balance(&2), 2000); -// // index 1 (account 2) becomes zombie -// assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); -// assert_eq!(Balances::total_balance(&2), 0); -// assert_eq!(Balances::total_balance(&5), 1901); -// assert_eq!(System::account_nonce(&2), 0); -// }); -// } - -// #[test] -// fn balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 42); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 42 })); -// assert_eq!(Balances::free_balance(1), 42); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::total_balance(&1), 42); -// assert_eq!(Balances::free_balance(2), 0); -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::total_balance(&2), 0); -// }); -// } - -// #[test] -// fn balance_transfer_works() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); -// assert_eq!(Balances::total_balance(&1), 42); -// assert_eq!(Balances::total_balance(&2), 69); -// }); -// } - -// #[test] -// fn force_transfer_works() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_noop!( -// Balances::force_transfer(Some(2).into(), 1, 2, 69), -// BadOrigin, -// ); -// assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); -// assert_eq!(Balances::total_balance(&1), 42); -// assert_eq!(Balances::total_balance(&2), 69); -// }); -// } - -// #[test] -// fn reserving_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 111); -// assert_eq!(Balances::reserved_balance(1), 0); - -// assert_ok!(Balances::reserve(&1, 69)); - -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 42); -// assert_eq!(Balances::reserved_balance(1), 69); -// }); -// } - -// #[test] -// fn balance_transfer_when_reserved_should_not_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 69)); -// assert_noop!( -// Balances::transfer(Some(1).into(), 2, 69), -// Error::<$test, _>::InsufficientBalance, -// ); -// }); -// } - -// #[test] -// fn deducting_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 69)); -// assert_eq!(Balances::free_balance(1), 42); -// }); -// } - -// #[test] -// fn refunding_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 42); -// assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); -// Balances::unreserve(&1, 69); -// assert_eq!(Balances::free_balance(1), 111); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn slashing_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 69)); -// assert!(Balances::slash(&1, 69).1.is_zero()); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 42); -// assert_eq!(>::get(), 42); -// }); -// } - -// #[test] -// fn withdrawing_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&2, 111); -// let _ = Balances::withdraw( -// &2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive -// ); -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Withdraw { who: 2, amount: 11 })); -// assert_eq!(Balances::free_balance(2), 100); -// assert_eq!(>::get(), 100); -// }); -// } - -// #[test] -// fn slashing_incomplete_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 42); -// assert_ok!(Balances::reserve(&1, 21)); -// assert_eq!(Balances::slash(&1, 69).1, 27); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(>::get(), 0); -// }); -// } - -// #[test] -// fn unreserving_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 111)); -// Balances::unreserve(&1, 42); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 42); -// }); -// } - -// #[test] -// fn slashing_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 111)); -// assert_eq!(Balances::slash_reserved(&1, 42).1, 0); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(>::get(), 69); -// }); -// } - -// #[test] -// fn slashing_incomplete_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 42)); -// assert_eq!(Balances::slash_reserved(&1, 69).1, 27); -// assert_eq!(Balances::free_balance(1), 69); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(>::get(), 69); -// }); -// } - -// #[test] -// fn repatriating_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 1); -// assert_ok!(Balances::reserve(&1, 110)); -// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); -// System::assert_last_event( -// RuntimeEvent::Balances(crate::Event::ReserveRepatriated { from: 1, to: 2, amount: 41, destination_status: Status::Free }) -// ); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::free_balance(2), 42); -// }); -// } - -// #[test] -// fn transferring_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 1); -// assert_ok!(Balances::reserve(&1, 110)); -// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(2), 41); -// assert_eq!(Balances::free_balance(2), 1); -// }); -// } - -// #[test] -// fn transferring_reserved_balance_to_yourself_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// assert_ok!(Balances::reserve(&1, 50)); -// assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Status::Free), 0); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance(1), 0); - -// assert_ok!(Balances::reserve(&1, 50)); -// assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Status::Free), 10); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn transferring_reserved_balance_to_nonexistent_should_fail() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 111)); -// assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); -// }); -// } - -// #[test] -// fn transferring_incomplete_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 1); -// assert_ok!(Balances::reserve(&1, 41)); -// assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Status::Free), 28); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::free_balance(1), 69); -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::free_balance(2), 42); -// }); -// } - -// #[test] -// fn transferring_too_high_value_should_not_panic() { -// <$ext_builder>::default().build().execute_with(|| { -// Balances::make_free_balance_be(&1, u64::MAX); -// Balances::make_free_balance_be(&2, 1); - -// assert_err!( -// Balances::transfer(Some(1).into(), 2, u64::MAX), -// ArithmeticError::Overflow, -// ); - -// assert_eq!(Balances::free_balance(1), u64::MAX); -// assert_eq!(Balances::free_balance(2), 1); -// }); -// } - -// #[test] -// fn account_create_on_free_too_low_with_other() { -// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 100); -// assert_eq!(>::get(), 100); - -// // No-op. -// let _ = Balances::deposit_creating(&2, 50); -// assert_eq!(Balances::free_balance(2), 0); -// assert_eq!(>::get(), 100); -// }) -// } - -// #[test] -// fn account_create_on_free_too_low() { -// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { -// // No-op. -// let _ = Balances::deposit_creating(&2, 50); -// assert_eq!(Balances::free_balance(2), 0); -// assert_eq!(>::get(), 0); -// }) -// } - -// #[test] -// fn account_removal_on_free_too_low() { -// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { -// assert_eq!(>::get(), 0); - -// // Setup two accounts with free balance above the existential threshold. -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 110); - -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::free_balance(2), 110); -// assert_eq!(>::get(), 220); - -// // Transfer funds from account 1 of such amount that after this transfer -// // the balance of account 1 will be below the existential threshold. -// // This should lead to the removal of all balance of this account. -// assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); - -// // Verify free balance removal of account 1. -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::free_balance(2), 130); - -// // Verify that TotalIssuance tracks balance removal when free balance is too low. -// assert_eq!(>::get(), 130); -// }); -// } - -// #[test] -// fn burn_must_work() { -// <$ext_builder>::default().monied(true).build().execute_with(|| { -// let init_total_issuance = Balances::total_issuance(); -// let imbalance = Balances::burn(10); -// assert_eq!(Balances::total_issuance(), init_total_issuance - 10); -// drop(imbalance); -// assert_eq!(Balances::total_issuance(), init_total_issuance); -// }); -// } - -// #[test] -// fn transfer_keep_alive_works() { -// <$ext_builder>::default().existential_deposit(1).build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 100); -// assert_noop!( -// Balances::transfer_keep_alive(Some(1).into(), 2, 100), -// Error::<$test, _>::KeepAlive -// ); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 0); -// }); -// } - -// #[test] -// #[should_panic = "the balance of any account should always be at least the existential deposit."] -// fn cannot_set_genesis_value_below_ed() { -// ($existential_deposit).with(|v| *v.borrow_mut() = 11); -// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); -// let _ = pallet_balances::GenesisConfig::<$test> { -// balances: vec![(1, 10)], -// }.assimilate_storage(&mut t).unwrap(); -// } - -// #[test] -// #[should_panic = "duplicate balances in genesis."] -// fn cannot_set_genesis_value_twice() { -// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); -// let _ = pallet_balances::GenesisConfig::<$test> { -// balances: vec![(1, 10), (2, 20), (1, 15)], -// }.assimilate_storage(&mut t).unwrap(); -// } - -// #[test] -// fn dust_moves_between_free_and_reserved() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// // Set balance to free and reserved at the existential deposit -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); -// // Check balance -// assert_eq!(Balances::free_balance(1), 100); -// assert_eq!(Balances::reserved_balance(1), 0); - -// // Reserve some free balance -// assert_ok!(Balances::reserve(&1, 50)); -// // Check balance, the account should be ok. -// assert_eq!(Balances::free_balance(1), 50); -// assert_eq!(Balances::reserved_balance(1), 50); - -// // Reserve the rest of the free balance -// assert_ok!(Balances::reserve(&1, 50)); -// // Check balance, the account should be ok. -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 100); - -// // Unreserve everything -// Balances::unreserve(&1, 100); -// // Check balance, all 100 should move to free_balance -// assert_eq!(Balances::free_balance(1), 100); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn account_deleted_when_just_dust() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// // Set balance to free and reserved at the existential deposit -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 50, 50)); -// // Check balance -// assert_eq!(Balances::free_balance(1), 50); -// assert_eq!(Balances::reserved_balance(1), 50); - -// // Reserve some free balance -// let res = Balances::slash(&1, 1); -// assert_eq!(res, (NegativeImbalance::new(1), 0)); - -// // The account should be dead. -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn emit_events_with_reserve_and_unreserve() { -// <$ext_builder>::default() -// .build() -// .execute_with(|| { -// let _ = Balances::deposit_creating(&1, 100); - -// System::set_block_number(2); -// assert_ok!(Balances::reserve(&1, 10)); - -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { who: 1, amount: 10 })); - -// System::set_block_number(3); -// assert!(Balances::unreserve(&1, 5).is_zero()); - -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); - -// System::set_block_number(4); -// assert_eq!(Balances::unreserve(&1, 6), 1); - -// // should only unreserve 5 -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); -// }); -// } - -// #[test] -// fn emit_events_with_existential_deposit() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), -// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), -// ] -// ); - -// let res = Balances::slash(&1, 1); -// assert_eq!(res, (NegativeImbalance::new(1), 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), -// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), -// ] -// ); -// }); -// } - -// #[test] -// fn emit_events_with_no_existential_deposit_suicide() { -// <$ext_builder>::default() -// .existential_deposit(1) -// .build() -// .execute_with(|| { -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), -// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), -// ] -// ); - -// let res = Balances::slash(&1, 100); -// assert_eq!(res, (NegativeImbalance::new(100), 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), -// ] -// ); -// }); -// } - -// #[test] -// fn slash_loop_works() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// /* User has no reference counter, so they can die in these scenarios */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 900 })); - -// // SCENARIO: Slash will kill account because not enough balance left. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); -// // Account is killed -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash will kill account, and report missing slash amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed full free_balance, and reports 300 not slashed -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); -// // Account is dead -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, but keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, and kill. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); -// // Account is dead because 50 reserved balance is not enough to keep alive -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash can take as much as possible from reserved, kill, and report missing amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); -// // Account is super dead -// assert!(!System::account_exists(&1)); - -// /* User will now have a reference counter on them, keeping them alive in these scenarios */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Slash will take as much as possible without killing account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(900), 50)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash will not kill account, and report missing slash amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed full free_balance minus ED, and reports 400 not slashed -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(900), 400)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, but keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, but keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); -// // Slashed full free_balance and 250 of reserved balance to leave ED -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take as much as possible from reserved and report missing amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1150), 150)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // Slash on non-existent account is okay. -// assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); -// }); -// } - -// #[test] -// fn slash_reserved_loop_works() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// /* User has no reference counter, so they can die in these scenarios */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Slash would kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(1_000), 0)); -// // Account is dead -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash would kill account, and reports left over slash. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); -// // Account is dead -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash does not take from free balance. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 300, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); -// // Account is alive because of free balance -// assert!(System::account_exists(&1)); - -// /* User has a reference counter, so they cannot die */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Slash as much as possible without killing. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed as much as possible -// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(950), 50)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash reports correctly, where reserved is needed to keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed as much as possible -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(950), 350)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash reports correctly, where full reserved is removed. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 1_000)); -// // Slashed as much as possible -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // Slash on non-existent account is okay. -// assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); -// }); -// } - -// #[test] -// fn operations_on_dead_account_should_not_change_state() { -// // These functions all use `mutate_account` which may introduce a storage change when -// // the account never existed to begin with, and shouldn't exist in the end. -// <$ext_builder>::default() -// .existential_deposit(0) -// .build() -// .execute_with(|| { -// assert!(!frame_system::Account::::contains_key(&1337)); - -// // Unreserve -// assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); -// // Reserve -// assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); -// // Slash Reserve -// assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); -// // Repatriate Reserve -// assert_noop!(Balances::repatriate_reserved(&1337, &1338, 42, Status::Free), Error::::DeadAccount); -// // Slash -// assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); -// }); -// } - -// #[test] -// fn transfer_keep_alive_all_free_succeed() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 100, 100)); -// assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 100); -// }); -// } - -// #[test] -// fn transfer_all_works() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and allow death -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); -// assert_eq!(Balances::total_balance(&1), 0); -// assert_eq!(Balances::total_balance(&2), 200); - -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and keep alive -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 100); - -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and allow death w/ reserved -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); -// assert_eq!(Balances::total_balance(&1), 0); -// assert_eq!(Balances::total_balance(&2), 200); - -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and keep alive w/ reserved -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 110); -// }); -// } - -// #[test] -// fn named_reserve_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// let id_1 = [1u8; 8]; -// let id_2 = [2u8; 8]; -// let id_3 = [3u8; 8]; - -// // reserve - -// assert_noop!(Balances::reserve_named(&id_1, &1, 112), Error::::InsufficientBalance); - -// assert_ok!(Balances::reserve_named(&id_1, &1, 12)); - -// assert_eq!(Balances::reserved_balance(1), 12); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - -// assert_ok!(Balances::reserve_named(&id_1, &1, 2)); - -// assert_eq!(Balances::reserved_balance(1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - -// assert_ok!(Balances::reserve_named(&id_2, &1, 23)); - -// assert_eq!(Balances::reserved_balance(1), 37); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); +// This file is part of Substrate. + +// Copyright (C) 2017-2022 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. + +//! Macro for creating the tests for the module. + +#![cfg(test)] + +#[macro_export] +macro_rules! decl_tests { + ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { + + use crate::*; + use sp_runtime::{ArithmeticError, TokenError, FixedPointNumber, traits::{SignedExtension, BadOrigin}}; + use frame_support::{ + assert_noop, assert_storage_noop, assert_ok, assert_err, + traits::{ + LockableCurrency, LockIdentifier, WithdrawReasons, + Currency, ReservableCurrency, ExistenceRequirement::AllowDeath + } + }; + use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; + use frame_system::RawOrigin; + + const ID_1: LockIdentifier = *b"1 "; + const ID_2: LockIdentifier = *b"2 "; + + pub const CALL: &<$test as frame_system::Config>::RuntimeCall = + &RuntimeCall::Balances(pallet_balances::Call::transfer { dest: 0, value: 0 }); + + /// create a transaction info struct from weight. Handy to avoid building the whole struct. + pub fn info_from_weight(w: Weight) -> DispatchInfo { + DispatchInfo { weight: w, ..Default::default() } + } + + fn events() -> Vec { + let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + + System::reset_events(); + + evt + } + + #[test] + fn basic_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 5, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn account_should_be_reaped() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); + // Check that the account is dead. + assert!(!frame_system::Account::::contains_key(&1)); + }); + } + + #[test] + fn reap_failed_due_to_provider_and_consumer() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + // SCENARIO: only one provider and there are remaining consumers. + assert_ok!(System::inc_consumers(&1)); + assert!(!System::can_dec_provider(&1)); + assert_noop!( + >::transfer(&1, &2, 10, AllowDeath), + Error::<$test, _>::KeepAlive + ); + assert!(System::account_exists(&1)); + assert_eq!(Balances::free_balance(1), 10); + + // SCENARIO: more than one provider, but will not kill account due to other provider. + assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); + assert_eq!(System::providers(&1), 2); + assert!(System::can_dec_provider(&1)); + assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); + assert_eq!(System::providers(&1), 1); + assert!(System::account_exists(&1)); + assert_eq!(Balances::free_balance(1), 0); + }); + } + + #[test] + fn partial_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn lock_removal_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); + Balances::remove_lock(ID_1, &1); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn lock_replacement_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn double_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn combination_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); + Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn lock_value_extension_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 3, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn lock_reasons_should_work() { + <$ext_builder>::default() + .existential_deposit(1) + .monied(true) + .build() + .execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::<$test>::put( + Multiplier::saturating_from_integer(1) + ); + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); + assert_noop!( + >::transfer(&1, &2, 1, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + assert_noop!( + >::reserve(&1, 1), + Error::<$test, _>::LiquidityRestrictions, + ); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), + &1, + CALL, + &info_from_weight(Weight::from_ref_time(1)), + 1, + ).is_err()); + assert_ok!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(0), + &1, + CALL, + &info_from_weight(Weight::from_ref_time(1)), + 1, + )); + + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + assert_ok!(>::reserve(&1, 1)); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), + &1, + CALL, + &info_from_weight(Weight::from_ref_time(1)), + 1, + ).is_err()); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(0), + &1, + CALL, + &info_from_weight(Weight::from_ref_time(1)), + 1, + ).is_err()); + }); + } + + #[test] + fn lock_block_number_extension_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + System::set_block_number(2); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 3, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn lock_reasons_extension_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn default_indexing_on_new_accounts_should_not_work2() { + <$ext_builder>::default() + .existential_deposit(10) + .monied(true) + .build() + .execute_with(|| { + // account 5 should not exist + // ext_deposit is 10, value is 9, not satisfies for ext_deposit + assert_noop!( + Balances::transfer(Some(1).into(), 5, 9), + Error::<$test, _>::ExistentialDeposit, + ); + assert_eq!(Balances::free_balance(1), 100); + }); + } + + #[test] + fn reserved_balance_should_prevent_reclaim_count() { + <$ext_builder>::default() + .existential_deposit(256 * 1) + .monied(true) + .build() + .execute_with(|| { + System::inc_account_nonce(&2); + assert_eq!(Balances::total_balance(&2), 256 * 20); + + assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved + assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." + assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. + assert_eq!(System::account_nonce(&2), 1); + + // account 4 tries to take index 1 for account 5. + assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); + assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); + + assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed + // "reserve" account reduced to 255 (below ED) so account deleted + assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(System::account_nonce(&2), 0); // nonce zero + + // account 4 tries to take index 1 again for account 6. + assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); + assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); + }); + } + + #[test] + fn reward_should_work() { + <$ext_builder>::default().monied(true).build().execute_with(|| { + assert_eq!(Balances::total_balance(&1), 10); + assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 })); + assert_eq!(Balances::total_balance(&1), 20); + assert_eq!(>::get(), 120); + }); + } + + #[test] + fn dust_account_removal_should_work() { + <$ext_builder>::default() + .existential_deposit(100) + .monied(true) + .build() + .execute_with(|| { + System::inc_account_nonce(&2); + assert_eq!(System::account_nonce(&2), 1); + assert_eq!(Balances::total_balance(&2), 2000); + // index 1 (account 2) becomes zombie + assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); + assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(Balances::total_balance(&5), 1901); + assert_eq!(System::account_nonce(&2), 0); + }); + } + + #[test] + fn balance_works() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 42 })); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::total_balance(&2), 0); + }); + } + + #[test] + fn balance_transfer_works() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); + } + + #[test] + fn force_transfer_works() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_noop!( + Balances::force_transfer(Some(2).into(), 1, 2, 69), + BadOrigin, + ); + assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); + } + + #[test] + fn reserving_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_ok!(Balances::reserve(&1, 69)); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 69); + }); + } + + #[test] + fn balance_transfer_when_reserved_should_not_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert_noop!( + Balances::transfer(Some(1).into(), 2, 69), + Error::<$test, _>::InsufficientBalance, + ); + }); + } + + #[test] + fn deducting_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert_eq!(Balances::free_balance(1), 42); + }); + } + + #[test] + fn refunding_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); + Balances::unreserve(&1, 69); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + + #[test] + fn slashing_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert!(Balances::slash(&1, 69).1.is_zero()); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 42); + assert_eq!(>::get(), 42); + }); + } + + #[test] + fn withdrawing_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&2, 111); + let _ = Balances::withdraw( + &2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive + ); + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Withdraw { who: 2, amount: 11 })); + assert_eq!(Balances::free_balance(2), 100); + assert_eq!(>::get(), 100); + }); + } + + #[test] + fn slashing_incomplete_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + assert_ok!(Balances::reserve(&1, 21)); + assert_eq!(Balances::slash(&1, 69).1, 27); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(>::get(), 0); + }); + } + + #[test] + fn unreserving_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 111)); + Balances::unreserve(&1, 42); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 42); + }); + } + + #[test] + fn slashing_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 111)); + assert_eq!(Balances::slash_reserved(&1, 42).1, 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(>::get(), 69); + }); + } + + #[test] + fn slashing_incomplete_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 42)); + assert_eq!(Balances::slash_reserved(&1, 69).1, 27); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(>::get(), 69); + }); + } + + #[test] + fn repatriating_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); + System::assert_last_event( + RuntimeEvent::Balances(crate::Event::ReserveRepatriated { from: 1, to: 2, amount: 41, destination_status: Status::Free }) + ); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); + }); + } + + #[test] + fn transferring_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(2), 41); + assert_eq!(Balances::free_balance(2), 1); + }); + } + + #[test] + fn transferring_reserved_balance_to_yourself_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + assert_ok!(Balances::reserve(&1, 50)); + assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Status::Free), 0); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_ok!(Balances::reserve(&1, 50)); + assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Status::Free), 10); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + + #[test] + fn transferring_reserved_balance_to_nonexistent_should_fail() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 111)); + assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); + }); + } + + #[test] + fn transferring_incomplete_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 41)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Status::Free), 28); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); + }); + } + + #[test] + fn transferring_too_high_value_should_not_panic() { + <$ext_builder>::default().build().execute_with(|| { + Balances::make_free_balance_be(&1, u64::MAX); + Balances::make_free_balance_be(&2, 1); + + assert_err!( + Balances::transfer(Some(1).into(), 2, u64::MAX), + ArithmeticError::Overflow, + ); + + assert_eq!(Balances::free_balance(1), u64::MAX); + assert_eq!(Balances::free_balance(2), 1); + }); + } + + #[test] + fn account_create_on_free_too_low_with_other() { + <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_eq!(>::get(), 100); + + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(>::get(), 100); + }) + } + + #[test] + fn account_create_on_free_too_low() { + <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(>::get(), 0); + }) + } + + #[test] + fn account_removal_on_free_too_low() { + <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { + assert_eq!(>::get(), 0); + + // Setup two accounts with free balance above the existential threshold. + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 110); + + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::free_balance(2), 110); + assert_eq!(>::get(), 220); + + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // This should lead to the removal of all balance of this account. + assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); + + // Verify free balance removal of account 1. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 130); + + // Verify that TotalIssuance tracks balance removal when free balance is too low. + assert_eq!(>::get(), 130); + }); + } + + #[test] + fn burn_must_work() { + <$ext_builder>::default().monied(true).build().execute_with(|| { + let init_total_issuance = Balances::total_issuance(); + let imbalance = Balances::burn(10); + assert_eq!(Balances::total_issuance(), init_total_issuance - 10); + drop(imbalance); + assert_eq!(Balances::total_issuance(), init_total_issuance); + }); + } + + #[test] + fn transfer_keep_alive_works() { + <$ext_builder>::default().existential_deposit(1).build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_noop!( + Balances::transfer_keep_alive(Some(1).into(), 2, 100), + Error::<$test, _>::KeepAlive + ); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 0); + }); + } + + #[test] + #[should_panic = "the balance of any account should always be at least the existential deposit."] + fn cannot_set_genesis_value_below_ed() { + ($existential_deposit).with(|v| *v.borrow_mut() = 11); + let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); + let _ = pallet_balances::GenesisConfig::<$test> { + balances: vec![(1, 10)], + }.assimilate_storage(&mut t).unwrap(); + } + + #[test] + #[should_panic = "duplicate balances in genesis."] + fn cannot_set_genesis_value_twice() { + let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); + let _ = pallet_balances::GenesisConfig::<$test> { + balances: vec![(1, 10), (2, 20), (1, 15)], + }.assimilate_storage(&mut t).unwrap(); + } + + #[test] + fn dust_moves_between_free_and_reserved() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // Set balance to free and reserved at the existential deposit + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + // Check balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 0); + + // Reserve some free balance + assert_ok!(Balances::reserve(&1, 50)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 50); + + // Reserve the rest of the free balance + assert_ok!(Balances::reserve(&1, 50)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 100); + + // Unreserve everything + Balances::unreserve(&1, 100); + // Check balance, all 100 should move to free_balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + + #[test] + fn account_deleted_when_just_dust() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // Set balance to free and reserved at the existential deposit + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 50, 50)); + // Check balance + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 50); + + // Reserve some free balance + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(1), 0)); + + // The account should be dead. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + + #[test] + fn emit_events_with_reserve_and_unreserve() { + <$ext_builder>::default() + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + + System::set_block_number(2); + assert_ok!(Balances::reserve(&1, 10)); + + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { who: 1, amount: 10 })); + + System::set_block_number(3); + assert!(Balances::unreserve(&1, 5).is_zero()); + + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); + + System::set_block_number(4); + assert_eq!(Balances::unreserve(&1, 6), 1); + + // should only unreserve 5 + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); + }); + } + + #[test] + fn emit_events_with_existential_deposit() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::NewAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), + RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), + ] + ); + + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(1), 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), + RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), + ] + ); + }); + } + + #[test] + fn emit_events_with_no_existential_deposit_suicide() { + <$ext_builder>::default() + .existential_deposit(1) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::NewAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), + RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), + ] + ); + + let res = Balances::slash(&1, 100); + assert_eq!(res, (NegativeImbalance::new(100), 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), + ] + ); + }); + } + + #[test] + fn slash_loop_works() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + /* User has no reference counter, so they can die in these scenarios */ + // SCENARIO: Slash would not kill account. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 900 })); + + // SCENARIO: Slash will kill account because not enough balance left. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); + // Account is killed + assert!(!System::account_exists(&1)); + + // SCENARIO: Over-slash will kill account, and report missing slash amount. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); + // Slashed full free_balance, and reports 300 not slashed + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); + // Account is dead + assert!(!System::account_exists(&1)); + + // SCENARIO: Over-slash can take from reserved, but keep alive. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); + // Slashed full free_balance and 300 of reserved balance + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash can take from reserved, and kill. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); + // Slashed full free_balance and 300 of reserved balance + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); + // Account is dead because 50 reserved balance is not enough to keep alive + assert!(!System::account_exists(&1)); + + // SCENARIO: Over-slash can take as much as possible from reserved, kill, and report missing amount. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); + // Slashed full free_balance and 300 of reserved balance + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); + // Account is super dead + assert!(!System::account_exists(&1)); + + /* User will now have a reference counter on them, keeping them alive in these scenarios */ + // SCENARIO: Slash would not kill account. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); + assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests + // Slashed completed in full + assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Slash will take as much as possible without killing account. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(900), 50)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash will not kill account, and report missing slash amount. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); + // Slashed full free_balance minus ED, and reports 400 not slashed + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(900), 400)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash can take from reserved, but keep alive. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); + // Slashed full free_balance and 300 of reserved balance + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash can take from reserved, but keep alive. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); + // Slashed full free_balance and 250 of reserved balance to leave ED + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash can take as much as possible from reserved and report missing amount. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); + // Slashed full free_balance and 300 of reserved balance + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1150), 150)); + // Account is still alive + assert!(System::account_exists(&1)); + + // Slash on non-existent account is okay. + assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); + }); + } + + #[test] + fn slash_reserved_loop_works() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + /* User has no reference counter, so they can die in these scenarios */ + // SCENARIO: Slash would not kill account. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Slash would kill account. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(1_000), 0)); + // Account is dead + assert!(!System::account_exists(&1)); + + // SCENARIO: Over-slash would kill account, and reports left over slash. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); + // Account is dead + assert!(!System::account_exists(&1)); + + // SCENARIO: Over-slash does not take from free balance. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 300, 1_000)); + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); + // Account is alive because of free balance + assert!(System::account_exists(&1)); + + /* User has a reference counter, so they cannot die */ + // SCENARIO: Slash would not kill account. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); + assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Slash as much as possible without killing. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); + // Slashed as much as possible + assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(950), 50)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash reports correctly, where reserved is needed to keep alive. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); + // Slashed as much as possible + assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(950), 350)); + // Account is still alive + assert!(System::account_exists(&1)); + + // SCENARIO: Over-slash reports correctly, where full reserved is removed. + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 1_000)); + // Slashed as much as possible + assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); + // Account is still alive + assert!(System::account_exists(&1)); + + // Slash on non-existent account is okay. + assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); + }); + } + + #[test] + fn operations_on_dead_account_should_not_change_state() { + // These functions all use `mutate_account` which may introduce a storage change when + // the account never existed to begin with, and shouldn't exist in the end. + <$ext_builder>::default() + .existential_deposit(0) + .build() + .execute_with(|| { + assert!(!frame_system::Account::::contains_key(&1337)); + + // Unreserve + assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); + // Reserve + assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); + // Slash Reserve + assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); + // Repatriate Reserve + assert_noop!(Balances::repatriate_reserved(&1337, &1338, 42, Status::Free), Error::::DeadAccount); + // Slash + assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); + }); + } + + #[test] + fn transfer_keep_alive_all_free_succeed() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 100, 100)); + assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 100); + }); + } + + #[test] + fn transfer_all_works() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // setup + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); + // transfer all and allow death + assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); + assert_eq!(Balances::total_balance(&1), 0); + assert_eq!(Balances::total_balance(&2), 200); + + // setup + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); + // transfer all and keep alive + assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 100); + + // setup + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); + // transfer all and allow death w/ reserved + assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); + assert_eq!(Balances::total_balance(&1), 0); + assert_eq!(Balances::total_balance(&2), 200); + + // setup + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); + // transfer all and keep alive w/ reserved + assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 110); + }); + } + + #[test] + fn named_reserve_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + let id_1 = [1u8; 8]; + let id_2 = [2u8; 8]; + let id_3 = [3u8; 8]; + + // reserve + + assert_noop!(Balances::reserve_named(&id_1, &1, 112), Error::::InsufficientBalance); + + assert_ok!(Balances::reserve_named(&id_1, &1, 12)); + + assert_eq!(Balances::reserved_balance(1), 12); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + + assert_ok!(Balances::reserve_named(&id_1, &1, 2)); + + assert_eq!(Balances::reserved_balance(1), 14); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + + assert_ok!(Balances::reserve_named(&id_2, &1, 23)); + + assert_eq!(Balances::reserved_balance(1), 37); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); -// assert_ok!(Balances::reserve(&1, 34)); + assert_ok!(Balances::reserve(&1, 34)); -// assert_eq!(Balances::reserved_balance(1), 71); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + assert_eq!(Balances::reserved_balance(1), 71); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 40); + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 40); -// assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); + assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); -// // unreserve + // unreserve -// assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); + assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); -// assert_eq!(Balances::reserved_balance(1), 61); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + assert_eq!(Balances::reserved_balance(1), 61); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); -// assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); + assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); -// assert_eq!(Balances::reserved_balance(1), 57); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + assert_eq!(Balances::reserved_balance(1), 57); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); -// assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); + assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); -// assert_eq!(Balances::reserved_balance(1), 54); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); + assert_eq!(Balances::reserved_balance(1), 54); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 57); + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 57); -// // slash_reserved_named + // slash_reserved_named -// assert_ok!(Balances::reserve_named(&id_1, &1, 10)); + assert_ok!(Balances::reserve_named(&id_1, &1, 10)); -// assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); + assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); -// assert_eq!(Balances::reserved_balance(1), 54); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); -// assert_eq!(Balances::total_balance(&1), 101); + assert_eq!(Balances::reserved_balance(1), 54); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); + assert_eq!(Balances::total_balance(&1), 101); -// assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); + assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); -// assert_eq!(Balances::reserved_balance(1), 49); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); -// assert_eq!(Balances::total_balance(&1), 96); + assert_eq!(Balances::reserved_balance(1), 49); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); + assert_eq!(Balances::total_balance(&1), 96); -// // repatriate_reserved_named + // repatriate_reserved_named -// let _ = Balances::deposit_creating(&2, 100); + let _ = Balances::deposit_creating(&2, 100); -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Reserved).unwrap(), 0); + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Reserved).unwrap(), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); -// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); -// assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); + assert_eq!(Balances::reserved_balance(&2), 10); -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Status::Reserved).unwrap(), 1); + assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Status::Reserved).unwrap(), 1); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); -// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); -// assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); + assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); + assert_eq!(Balances::reserved_balance(&2), 0); -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Free).unwrap(), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); -// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); -// assert_eq!(Balances::free_balance(&2), 110); + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Free).unwrap(), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); + assert_eq!(Balances::free_balance(&2), 110); -// // repatriate_reserved_named to self + // repatriate_reserved_named to self -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Status::Reserved).unwrap(), 5); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Status::Reserved).unwrap(), 5); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); -// assert_eq!(Balances::free_balance(&1), 47); + assert_eq!(Balances::free_balance(&1), 47); -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Status::Free).unwrap(), 10); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Status::Free).unwrap(), 10); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); -// assert_eq!(Balances::free_balance(&1), 52); -// }); -// } + assert_eq!(Balances::free_balance(&1), 52); + }); + } -// #[test] -// fn reserved_named_to_yourself_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); + #[test] + fn reserved_named_to_yourself_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); -// let id = [1u8; 8]; + let id = [1u8; 8]; -// assert_ok!(Balances::reserve_named(&id, &1, 50)); -// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Status::Free), 0); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_ok!(Balances::reserve_named(&id, &1, 50)); + assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Status::Free), 0); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_ok!(Balances::reserve_named(&id, &1, 50)); -// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Status::Free), 10); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// }); -// } + assert_ok!(Balances::reserve_named(&id, &1, 50)); + assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Status::Free), 10); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + }); + } -// #[test] -// fn ensure_reserved_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); + #[test] + fn ensure_reserved_named_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); -// let id = [1u8; 8]; + let id = [1u8; 8]; -// assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 15); + assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 15); -// assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 10); + assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 10); -// assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 20); -// }); -// } + assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 20); + }); + } -// #[test] -// fn unreserve_all_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); + #[test] + fn unreserve_all_named_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); -// let id = [1u8; 8]; + let id = [1u8; 8]; -// assert_ok!(Balances::reserve_named(&id, &1, 15)); + assert_ok!(Balances::reserve_named(&id, &1, 15)); -// assert_eq!(Balances::unreserve_all_named(&id, &1), 15); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_eq!(Balances::free_balance(&1), 111); - -// assert_eq!(Balances::unreserve_all_named(&id, &1), 0); -// }); -// } - -// #[test] -// fn slash_all_reserved_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::reserve_named(&id, &1, 15)); - -// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_eq!(Balances::free_balance(&1), 96); - -// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); -// }); -// } - -// #[test] -// fn repatriate_all_reserved_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// let _ = Balances::deposit_creating(&2, 10); -// let _ = Balances::deposit_creating(&3, 10); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::reserve_named(&id, &1, 15)); - -// assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Status::Reserved)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id, &2), 15); - -// assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Status::Free)); -// assert_eq!(Balances::reserved_balance_named(&id, &2), 0); -// assert_eq!(Balances::free_balance(&3), 25); -// }); -// } - -// #[test] -// fn set_balance_handles_killing_account() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(frame_system::Pallet::::inc_consumers(&1)); -// assert_noop!( -// Balances::set_balance(RuntimeOrigin::root(), 1, 0, 0), -// DispatchError::ConsumerRemaining, -// ); -// }); -// } - -// #[test] -// fn set_balance_handles_total_issuance() { -// <$ext_builder>::default().build().execute_with(|| { -// let old_total_issuance = Balances::total_issuance(); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1337, 69, 42)); -// assert_eq!(Balances::total_issuance(), old_total_issuance + 69 + 42); -// assert_eq!(Balances::total_balance(&1337), 69 + 42); -// assert_eq!(Balances::free_balance(&1337), 69); -// assert_eq!(Balances::reserved_balance(&1337), 42); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_set_balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_eq!(>::balance(&1337), 0); -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!(>::balance(&1337), 100); - -// assert_ok!(Balances::reserve(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); - -// assert_noop!(>::set_balance(&1337, 0), ArithmeticError::Underflow); - -// assert_ok!(>::set_balance(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 0); -// assert_eq!(Balances::reserved_balance(1337), 60); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_set_total_issuance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_eq!(>::total_issuance(), 0); -// >::set_total_issuance(100); -// assert_eq!(>::total_issuance(), 100); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_decrease_balance_simple_works() { -// <$ext_builder>::default().build().execute_with(|| { -// // An Account that starts at 100 -// assert_ok!(>::set_balance(&1337, 100)); -// // and reserves 50 -// assert_ok!(Balances::reserve(&1337, 50)); -// // and is decreased by 20 -// assert_ok!(>::decrease_balance(&1337, 20)); -// // should end up at 80. -// assert_eq!(>::balance(&1337), 80); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_decrease_balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!(>::balance(&1337), 100); - -// assert_noop!( -// >::decrease_balance(&1337, 101), -// TokenError::NoFunds -// ); -// assert_eq!( -// >::decrease_balance(&1337, 100), -// Ok(100) -// ); -// assert_eq!(>::balance(&1337), 0); - -// // free: 40, reserved: 60 -// assert_ok!(>::set_balance(&1337, 100)); -// assert_ok!(Balances::reserve(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); -// assert_noop!( -// >::decrease_balance(&1337, 41), -// TokenError::NoFunds -// ); -// assert_eq!( -// >::decrease_balance(&1337, 40), -// Ok(40) -// ); -// assert_eq!(>::balance(&1337), 60); -// assert_eq!(Balances::free_balance(1337), 0); -// assert_eq!(Balances::reserved_balance(1337), 60); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_decrease_balance_at_most_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!(>::balance(&1337), 100); - -// assert_eq!( -// >::decrease_balance_at_most(&1337, 101), -// 100 -// ); -// assert_eq!(>::balance(&1337), 0); - -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 100), -// 100 -// ); -// assert_eq!(>::balance(&1337), 0); - -// // free: 40, reserved: 60 -// assert_ok!(>::set_balance(&1337, 100)); -// assert_ok!(Balances::reserve(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 0), -// 0 -// ); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 10), -// 10 -// ); -// assert_eq!(Balances::free_balance(1337), 30); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 200), -// 30 -// ); -// assert_eq!(>::balance(&1337), 60); -// assert_eq!(Balances::free_balance(1337), 0); -// assert_eq!(Balances::reserved_balance(1337), 60); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_increase_balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_noop!( -// >::increase_balance(&1337, 0), -// TokenError::BelowMinimum -// ); -// assert_eq!( -// >::increase_balance(&1337, 1), -// Ok(1) -// ); -// assert_noop!( -// >::increase_balance(&1337, u64::MAX), -// ArithmeticError::Overflow -// ); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_increase_balance_at_most_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_eq!( -// >::increase_balance_at_most(&1337, 0), -// 0 -// ); -// assert_eq!( -// >::increase_balance_at_most(&1337, 1), -// 1 -// ); -// assert_eq!( -// >::increase_balance_at_most(&1337, u64::MAX), -// u64::MAX - 1 -// ); -// }); -// } -// } -// } + assert_eq!(Balances::unreserve_all_named(&id, &1), 15); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_eq!(Balances::free_balance(&1), 111); + + assert_eq!(Balances::unreserve_all_named(&id, &1), 0); + }); + } + + #[test] + fn slash_all_reserved_named_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + let id = [1u8; 8]; + + assert_ok!(Balances::reserve_named(&id, &1, 15)); + + assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_eq!(Balances::free_balance(&1), 96); + + assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); + }); + } + + #[test] + fn repatriate_all_reserved_named_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + let _ = Balances::deposit_creating(&2, 10); + let _ = Balances::deposit_creating(&3, 10); + + let id = [1u8; 8]; + + assert_ok!(Balances::reserve_named(&id, &1, 15)); + + assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Status::Reserved)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id, &2), 15); + + assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Status::Free)); + assert_eq!(Balances::reserved_balance_named(&id, &2), 0); + assert_eq!(Balances::free_balance(&3), 25); + }); + } + + #[test] + fn set_balance_handles_killing_account() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(frame_system::Pallet::::inc_consumers(&1)); + assert_noop!( + Balances::set_balance(RuntimeOrigin::root(), 1, 0, 0), + DispatchError::ConsumerRemaining, + ); + }); + } + + #[test] + fn set_balance_handles_total_issuance() { + <$ext_builder>::default().build().execute_with(|| { + let old_total_issuance = Balances::total_issuance(); + assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1337, 69, 42)); + assert_eq!(Balances::total_issuance(), old_total_issuance + 69 + 42); + assert_eq!(Balances::total_balance(&1337), 69 + 42); + assert_eq!(Balances::free_balance(&1337), 69); + assert_eq!(Balances::reserved_balance(&1337), 42); + }); + } + + #[test] + fn fungible_unbalanced_trait_set_balance_works() { + <$ext_builder>::default().build().execute_with(|| { + assert_eq!(>::balance(&1337), 0); + assert_ok!(>::set_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + + assert_ok!(Balances::reserve(&1337, 60)); + assert_eq!(Balances::free_balance(1337) , 40); + assert_eq!(Balances::reserved_balance(1337), 60); + + assert_noop!(>::set_balance(&1337, 0), ArithmeticError::Underflow); + + assert_ok!(>::set_balance(&1337, 60)); + assert_eq!(Balances::free_balance(1337) , 0); + assert_eq!(Balances::reserved_balance(1337), 60); + }); + } + + #[test] + fn fungible_unbalanced_trait_set_total_issuance_works() { + <$ext_builder>::default().build().execute_with(|| { + assert_eq!(>::total_issuance(), 0); + >::set_total_issuance(100); + assert_eq!(>::total_issuance(), 100); + }); + } + + #[test] + fn fungible_unbalanced_trait_decrease_balance_simple_works() { + <$ext_builder>::default().build().execute_with(|| { + // An Account that starts at 100 + assert_ok!(>::set_balance(&1337, 100)); + // and reserves 50 + assert_ok!(Balances::reserve(&1337, 50)); + // and is decreased by 20 + assert_ok!(>::decrease_balance(&1337, 20)); + // should end up at 80. + assert_eq!(>::balance(&1337), 80); + }); + } + + #[test] + fn fungible_unbalanced_trait_decrease_balance_works() { + <$ext_builder>::default().build().execute_with(|| { + assert_ok!(>::set_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + + assert_noop!( + >::decrease_balance(&1337, 101), + TokenError::NoFunds + ); + assert_eq!( + >::decrease_balance(&1337, 100), + Ok(100) + ); + assert_eq!(>::balance(&1337), 0); + + // free: 40, reserved: 60 + assert_ok!(>::set_balance(&1337, 100)); + assert_ok!(Balances::reserve(&1337, 60)); + assert_eq!(Balances::free_balance(1337) , 40); + assert_eq!(Balances::reserved_balance(1337), 60); + assert_noop!( + >::decrease_balance(&1337, 41), + TokenError::NoFunds + ); + assert_eq!( + >::decrease_balance(&1337, 40), + Ok(40) + ); + assert_eq!(>::balance(&1337), 60); + assert_eq!(Balances::free_balance(1337), 0); + assert_eq!(Balances::reserved_balance(1337), 60); + }); + } + + #[test] + fn fungible_unbalanced_trait_decrease_balance_at_most_works() { + <$ext_builder>::default().build().execute_with(|| { + assert_ok!(>::set_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + + assert_eq!( + >::decrease_balance_at_most(&1337, 101), + 100 + ); + assert_eq!(>::balance(&1337), 0); + + assert_ok!(>::set_balance(&1337, 100)); + assert_eq!( + >::decrease_balance_at_most(&1337, 100), + 100 + ); + assert_eq!(>::balance(&1337), 0); + + // free: 40, reserved: 60 + assert_ok!(>::set_balance(&1337, 100)); + assert_ok!(Balances::reserve(&1337, 60)); + assert_eq!(Balances::free_balance(1337) , 40); + assert_eq!(Balances::reserved_balance(1337), 60); + assert_eq!( + >::decrease_balance_at_most(&1337, 0), + 0 + ); + assert_eq!(Balances::free_balance(1337) , 40); + assert_eq!(Balances::reserved_balance(1337), 60); + assert_eq!( + >::decrease_balance_at_most(&1337, 10), + 10 + ); + assert_eq!(Balances::free_balance(1337), 30); + assert_eq!( + >::decrease_balance_at_most(&1337, 200), + 30 + ); + assert_eq!(>::balance(&1337), 60); + assert_eq!(Balances::free_balance(1337), 0); + assert_eq!(Balances::reserved_balance(1337), 60); + }); + } + + #[test] + fn fungible_unbalanced_trait_increase_balance_works() { + <$ext_builder>::default().build().execute_with(|| { + assert_noop!( + >::increase_balance(&1337, 0), + TokenError::BelowMinimum + ); + assert_eq!( + >::increase_balance(&1337, 1), + Ok(1) + ); + assert_noop!( + >::increase_balance(&1337, u64::MAX), + ArithmeticError::Overflow + ); + }); + } + + #[test] + fn fungible_unbalanced_trait_increase_balance_at_most_works() { + <$ext_builder>::default().build().execute_with(|| { + assert_eq!( + >::increase_balance_at_most(&1337, 0), + 0 + ); + assert_eq!( + >::increase_balance_at_most(&1337, 1), + 1 + ); + assert_eq!( + >::increase_balance_at_most(&1337, u64::MAX), + u64::MAX - 1 + ); + }); + } + } +} diff --git a/pallets/balances/src/tests_composite.rs b/pallets/balances/src/tests_composite.rs index 07e3232fb..8089b5f0d 100644 --- a/pallets/balances/src/tests_composite.rs +++ b/pallets/balances/src/tests_composite.rs @@ -1,149 +1,154 @@ -// // This file is part of Substrate. +// This file is part of Substrate. -// // Copyright (C) 2018-2022 Parity Technologies (UK) Ltd. -// // SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2018-2022 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. +// 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 +//! Test utilities -// #![cfg(test)] +#![cfg(test)] -// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; -// use frame_support::{ -// dispatch::DispatchInfo, -// parameter_types, -// traits::{ConstU32, ConstU64, ConstU8}, -// weights::{IdentityFee, Weight}, -// }; -// use pallet_transaction_payment::CurrencyAdapter; -// use sp_core::H256; -// use sp_io; -// use sp_runtime::{testing::Header, traits::IdentityLookup}; -// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -// type Block = frame_system::mocking::MockBlock; +use crate::{self as pallet_balances, decl_tests, Config, Pallet}; +use frame_support::{ + dispatch::DispatchInfo, + parameter_types, + traits::{ConstU32, ConstU64, ConstU8}, + weights::{IdentityFee, Weight}, +}; +use pallet_transaction_payment::CurrencyAdapter; +use sp_core::H256; +use sp_io; +use sp_runtime::{testing::Header, traits::IdentityLookup}; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; -// frame_support::construct_runtime!( -// pub enum Test where -// Block = Block, -// NodeBlock = Block, -// UncheckedExtrinsic = UncheckedExtrinsic, -// { -// System: frame_system::{Pallet, Call, Config, Storage, Event}, -// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, -// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, -// } -// ); +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + } +); -// parameter_types! { -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max( -// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), -// ); -// pub static ExistentialDeposit: u64 = 0; -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = frame_support::traits::Everything; -// type BlockWeights = BlockWeights; -// type BlockLength = (); -// type DbWeight = (); -// type RuntimeOrigin = RuntimeOrigin; -// type Index = u64; -// type BlockNumber = u64; -// type RuntimeCall = RuntimeCall; -// type Hash = H256; -// type Hashing = ::sp_runtime::traits::BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type RuntimeEvent = RuntimeEvent; -// type BlockHashCount = ConstU64<250>; -// type Version = (); -// type PalletInfo = PalletInfo; -// type AccountData = super::AccountData; -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// type SS58Prefix = (); -// type OnSetCode = (); -// type MaxConsumers = frame_support::traits::ConstU32<16>; -// } +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), + ); + pub static ExistentialDeposit: u64 = 0; +} +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = u64; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = super::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} -// impl pallet_transaction_payment::Config for Test { -// type RuntimeEvent = RuntimeEvent; -// type OnChargeTransaction = CurrencyAdapter, ()>; -// type OperationalFeeMultiplier = ConstU8<5>; -// type WeightToFee = IdentityFee; -// type LengthToFee = IdentityFee; -// type FeeMultiplierUpdate = (); -// } +impl pallet_transaction_payment::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter, ()>; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = IdentityFee; + type FeeMultiplierUpdate = (); +} -// impl Config for Test { -// type Balance = u64; -// type DustRemoval = (); -// type RuntimeEvent = RuntimeEvent; -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = frame_system::Pallet; -// type MaxLocks = (); -// type MaxReserves = ConstU32<2>; -// type ReserveIdentifier = [u8; 8]; -// type WeightInfo = (); -// } +impl Config for Test { + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = frame_system::Pallet; + type MaxLocks = (); + type MaxReserves = ConstU32<2>; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} -// pub struct ExtBuilder { -// existential_deposit: u64, -// monied: bool, -// } -// impl Default for ExtBuilder { -// fn default() -> Self { -// Self { existential_deposit: 1, monied: false } -// } -// } -// impl ExtBuilder { -// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { -// self.existential_deposit = existential_deposit; -// self -// } -// pub fn monied(mut self, monied: bool) -> Self { -// self.monied = monied; -// self -// } -// pub fn set_associated_consts(&self) { -// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); -// } -// pub fn build(self) -> sp_io::TestExternalities { -// self.set_associated_consts(); -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { -// balances: if self.monied { -// vec![ -// (1, 10 * self.existential_deposit), -// (2, 20 * self.existential_deposit), -// (3, 30 * self.existential_deposit), -// (4, 40 * self.existential_deposit), -// (12, 10 * self.existential_deposit), -// ] -// } else { -// vec![] -// }, -// } -// .assimilate_storage(&mut t) -// .unwrap(); +pub struct ExtBuilder { + existential_deposit: u64, + monied: bool, +} +impl Default for ExtBuilder { + fn default() -> Self { + Self { + existential_deposit: 1, + monied: false, + } + } +} +impl ExtBuilder { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + self.existential_deposit = existential_deposit; + self + } + pub fn monied(mut self, monied: bool) -> Self { + self.monied = monied; + self + } + pub fn set_associated_consts(&self) { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + } + pub fn build(self) -> sp_io::TestExternalities { + self.set_associated_consts(); + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + pallet_balances::GenesisConfig:: { + balances: if self.monied { + vec![ + (1, 10 * self.existential_deposit), + (2, 20 * self.existential_deposit), + (3, 30 * self.existential_deposit), + (4, 40 * self.existential_deposit), + (12, 10 * self.existential_deposit), + ] + } else { + vec![] + }, + } + .assimilate_storage(&mut t) + .unwrap(); -// let mut ext = sp_io::TestExternalities::new(t); -// ext.execute_with(|| System::set_block_number(1)); -// ext -// } -// } + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} -// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } +decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } diff --git a/pallets/balances/src/tests_local.rs b/pallets/balances/src/tests_local.rs index 4f2cd2483..1f43af37d 100644 --- a/pallets/balances/src/tests_local.rs +++ b/pallets/balances/src/tests_local.rs @@ -1,191 +1,212 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2018-2022 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 - -// #![cfg(test)] - -// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; -// use frame_support::{ -// dispatch::DispatchInfo, -// parameter_types, -// traits::{ConstU32, ConstU64, ConstU8, StorageMapShim}, -// weights::{IdentityFee, Weight}, -// }; -// use pallet_transaction_payment::CurrencyAdapter; -// use sp_core::H256; -// use sp_io; -// use sp_runtime::{testing::Header, traits::IdentityLookup}; - -// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -// type Block = frame_system::mocking::MockBlock; - -// frame_support::construct_runtime!( -// pub struct Test where -// Block = Block, -// NodeBlock = Block, -// UncheckedExtrinsic = UncheckedExtrinsic, -// { -// System: frame_system::{Pallet, Call, Config, Storage, Event}, -// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, -// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, -// } -// ); - -// parameter_types! { -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max( -// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), -// ); -// pub static ExistentialDeposit: u64 = 0; -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = frame_support::traits::Everything; -// type BlockWeights = BlockWeights; -// type BlockLength = (); -// type DbWeight = (); -// type RuntimeOrigin = RuntimeOrigin; -// type Index = u64; -// type BlockNumber = u64; -// type RuntimeCall = RuntimeCall; -// type Hash = H256; -// type Hashing = ::sp_runtime::traits::BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type RuntimeEvent = RuntimeEvent; -// type BlockHashCount = ConstU64<250>; -// type Version = (); -// type PalletInfo = PalletInfo; -// type AccountData = (); -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// type SS58Prefix = (); -// type OnSetCode = (); -// type MaxConsumers = frame_support::traits::ConstU32<16>; -// } - -// impl pallet_transaction_payment::Config for Test { -// type RuntimeEvent = RuntimeEvent; -// type OnChargeTransaction = CurrencyAdapter, ()>; -// type OperationalFeeMultiplier = ConstU8<5>; -// type WeightToFee = IdentityFee; -// type LengthToFee = IdentityFee; -// type FeeMultiplierUpdate = (); -// } - -// impl Config for Test { -// type Balance = u64; -// type DustRemoval = (); -// type RuntimeEvent = RuntimeEvent; -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = -// StorageMapShim, system::Provider, u64, super::AccountData>; -// type MaxLocks = ConstU32<50>; -// type MaxReserves = ConstU32<2>; -// type ReserveIdentifier = [u8; 8]; -// type WeightInfo = (); -// } - -// pub struct ExtBuilder { -// existential_deposit: u64, -// monied: bool, -// } -// impl Default for ExtBuilder { -// fn default() -> Self { -// Self { existential_deposit: 1, monied: false } -// } -// } -// impl ExtBuilder { -// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { -// self.existential_deposit = existential_deposit; -// self -// } -// pub fn monied(mut self, monied: bool) -> Self { -// self.monied = monied; -// if self.existential_deposit == 0 { -// self.existential_deposit = 1; -// } -// self -// } -// pub fn set_associated_consts(&self) { -// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); -// } -// pub fn build(self) -> sp_io::TestExternalities { -// self.set_associated_consts(); -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { -// balances: if self.monied { -// vec![ -// (1, 10 * self.existential_deposit), -// (2, 20 * self.existential_deposit), -// (3, 30 * self.existential_deposit), -// (4, 40 * self.existential_deposit), -// (12, 10 * self.existential_deposit), -// ] -// } else { -// vec![] -// }, -// } -// .assimilate_storage(&mut t) -// .unwrap(); - -// let mut ext = sp_io::TestExternalities::new(t); -// ext.execute_with(|| System::set_block_number(1)); -// ext -// } -// } - -// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } - -// #[test] -// fn emit_events_with_no_existential_deposit_suicide_with_dust() { -// ::default().existential_deposit(2).build().execute_with(|| { -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), -// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), -// ] -// ); - -// let res = Balances::slash(&1, 98); -// assert_eq!(res, (NegativeImbalance::new(98), 0)); - -// // no events -// assert_eq!( -// events(), -// [RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 98 })] -// ); - -// let res = Balances::slash(&1, 1); -// assert_eq!(res, (NegativeImbalance::new(1), 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 1 }), -// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }) -// ] -// ); -// }); -// } +// This file is part of Substrate. + +// Copyright (C) 2018-2022 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 + +#![cfg(test)] + +use crate::{self as pallet_balances, decl_tests, Config, Pallet}; +use frame_support::{ + dispatch::DispatchInfo, + parameter_types, + traits::{ConstU32, ConstU64, ConstU8, StorageMapShim}, + weights::{IdentityFee, Weight}, +}; +use pallet_transaction_payment::CurrencyAdapter; +use sp_core::H256; +use sp_io; +use sp_runtime::{testing::Header, traits::IdentityLookup}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub struct Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), + ); + pub static ExistentialDeposit: u64 = 0; +} +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = u64; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_transaction_payment::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter, ()>; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = IdentityFee; + type FeeMultiplierUpdate = (); +} + +impl Config for Test { + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = + StorageMapShim, system::Provider, u64, super::AccountData>; + type MaxLocks = ConstU32<50>; + type MaxReserves = ConstU32<2>; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} + +pub struct ExtBuilder { + existential_deposit: u64, + monied: bool, +} +impl Default for ExtBuilder { + fn default() -> Self { + Self { + existential_deposit: 1, + monied: false, + } + } +} +impl ExtBuilder { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + self.existential_deposit = existential_deposit; + self + } + pub fn monied(mut self, monied: bool) -> Self { + self.monied = monied; + if self.existential_deposit == 0 { + self.existential_deposit = 1; + } + self + } + pub fn set_associated_consts(&self) { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + } + pub fn build(self) -> sp_io::TestExternalities { + self.set_associated_consts(); + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + pallet_balances::GenesisConfig:: { + balances: if self.monied { + vec![ + (1, 10 * self.existential_deposit), + (2, 20 * self.existential_deposit), + (3, 30 * self.existential_deposit), + (4, 40 * self.existential_deposit), + (12, 10 * self.existential_deposit), + ] + } else { + vec![] + }, + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } + +#[test] +fn emit_events_with_no_existential_deposit_suicide_with_dust() { + ::default() + .existential_deposit(2) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::NewAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Endowed { + account: 1, + free_balance: 100 + }), + RuntimeEvent::Balances(crate::Event::BalanceSet { + who: 1, + free: 100, + reserved: 0 + }), + ] + ); + + let res = Balances::slash(&1, 98); + assert_eq!(res, (NegativeImbalance::new(98), 0)); + + // no events + assert_eq!( + events(), + [RuntimeEvent::Balances(crate::Event::Slashed { + who: 1, + amount: 98 + })] + ); + + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(1), 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::DustLost { + account: 1, + amount: 1 + }), + RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }) + ] + ); + }); +} diff --git a/pallets/balances/src/tests_reentrancy.rs b/pallets/balances/src/tests_reentrancy.rs index 61814e598..d251a90a2 100644 --- a/pallets/balances/src/tests_reentrancy.rs +++ b/pallets/balances/src/tests_reentrancy.rs @@ -1,264 +1,277 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2018-2022 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 setup for potential reentracy and lost updates of nested mutations. - -// #![cfg(test)] - -// use crate::{self as pallet_balances, Config}; -// use frame_support::{ -// parameter_types, -// traits::{ConstU32, ConstU64, StorageMapShim}, -// }; -// use sp_core::H256; -// use sp_io; -// use sp_runtime::{testing::Header, traits::IdentityLookup}; - -// use crate::*; -// use frame_support::{ -// assert_ok, -// traits::{Currency, ReservableCurrency}, -// }; -// use frame_system::RawOrigin; - -// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -// type Block = frame_system::mocking::MockBlock; - -// frame_support::construct_runtime!( -// pub enum Test where -// Block = Block, -// NodeBlock = Block, -// UncheckedExtrinsic = UncheckedExtrinsic, -// { -// System: frame_system::{Pallet, Call, Config, Storage, Event}, -// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, -// } -// ); - -// parameter_types! { -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max( -// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), -// ); -// pub static ExistentialDeposit: u64 = 0; -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = frame_support::traits::Everything; -// type BlockWeights = BlockWeights; -// type BlockLength = (); -// type DbWeight = (); -// type RuntimeOrigin = RuntimeOrigin; -// type Index = u64; -// type BlockNumber = u64; -// type RuntimeCall = RuntimeCall; -// type Hash = H256; -// type Hashing = ::sp_runtime::traits::BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type RuntimeEvent = RuntimeEvent; -// type BlockHashCount = ConstU64<250>; -// type Version = (); -// type PalletInfo = PalletInfo; -// type AccountData = (); -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// type SS58Prefix = (); -// type OnSetCode = (); -// type MaxConsumers = frame_support::traits::ConstU32<16>; -// } - -// pub struct OnDustRemoval; -// impl OnUnbalanced> for OnDustRemoval { -// fn on_nonzero_unbalanced(amount: NegativeImbalance) { -// assert_ok!(Balances::resolve_into_existing(&1, amount)); -// } -// } - -// impl Config for Test { -// type Balance = u64; -// type DustRemoval = OnDustRemoval; -// type RuntimeEvent = RuntimeEvent; -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = -// StorageMapShim, system::Provider, u64, super::AccountData>; -// type MaxLocks = ConstU32<50>; -// type MaxReserves = ConstU32<2>; -// type ReserveIdentifier = [u8; 8]; -// type WeightInfo = (); -// } - -// pub struct ExtBuilder { -// existential_deposit: u64, -// } -// impl Default for ExtBuilder { -// fn default() -> Self { -// Self { existential_deposit: 1 } -// } -// } -// impl ExtBuilder { -// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { -// self.existential_deposit = existential_deposit; -// self -// } - -// pub fn set_associated_consts(&self) { -// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); -// } - -// pub fn build(self) -> sp_io::TestExternalities { -// self.set_associated_consts(); -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { balances: vec![] } -// .assimilate_storage(&mut t) -// .unwrap(); -// let mut ext = sp_io::TestExternalities::new(t); -// ext.execute_with(|| System::set_block_number(1)); -// ext -// } -// } - -// #[test] -// fn transfer_dust_removal_tst1_should_work() { -// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { -// // Verification of reentrancy in dust removal -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - -// // In this transaction, account 2 free balance -// // drops below existential balance -// // and dust balance is removed from account 2 -// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 3, 450)); - -// // As expected dust balance is removed. -// assert_eq!(Balances::free_balance(&2), 0); - -// // As expected beneficiary account 3 -// // received the transfered fund. -// assert_eq!(Balances::free_balance(&3), 450); - -// // Dust balance is deposited to account 1 -// // during the process of dust removal. -// assert_eq!(Balances::free_balance(&1), 1050); - -// // Verify the events -// assert_eq!(System::events().len(), 12); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { -// from: 2, -// to: 3, -// amount: 450, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { -// account: 2, -// amount: 50, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { -// who: 1, -// amount: 50, -// })); -// }); -// } - -// #[test] -// fn transfer_dust_removal_tst2_should_work() { -// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { -// // Verification of reentrancy in dust removal -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - -// // In this transaction, account 2 free balance -// // drops below existential balance -// // and dust balance is removed from account 2 -// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 1, 450)); - -// // As expected dust balance is removed. -// assert_eq!(Balances::free_balance(&2), 0); - -// // Dust balance is deposited to account 1 -// // during the process of dust removal. -// assert_eq!(Balances::free_balance(&1), 1500); - -// // Verify the events -// assert_eq!(System::events().len(), 10); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { -// from: 2, -// to: 1, -// amount: 450, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { -// account: 2, -// amount: 50, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { -// who: 1, -// amount: 50, -// })); -// }); -// } - -// #[test] -// fn repatriating_reserved_balance_dust_removal_should_work() { -// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { -// // Verification of reentrancy in dust removal -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - -// // Reserve a value on account 2, -// // Such that free balance is lower than -// // Exestintial deposit. -// assert_ok!(Balances::reserve(&2, 450)); - -// // Transfer of reserved fund from slashed account 2 to -// // beneficiary account 1 -// assert_ok!(Balances::repatriate_reserved(&2, &1, 450, Status::Free), 0); - -// // Since free balance of account 2 is lower than -// // existential deposit, dust amount is -// // removed from the account 2 -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::free_balance(2), 0); - -// // account 1 is credited with reserved amount -// // together with dust balance during dust -// // removal. -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::free_balance(1), 1500); - -// // Verify the events -// assert_eq!(System::events().len(), 11); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { -// from: 2, -// to: 1, -// amount: 450, -// destination_status: Status::Free, -// })); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { -// account: 2, -// amount: 50, -// })); - -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { -// who: 1, -// amount: 50, -// })); -// }); -// } +// This file is part of Substrate. + +// Copyright (C) 2018-2022 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 setup for potential reentracy and lost updates of nested mutations. + +#![cfg(test)] + +use crate::{self as pallet_balances, Config}; +use frame_support::{ + parameter_types, + traits::{ConstU32, ConstU64, StorageMapShim}, +}; +use sp_core::H256; +use sp_io; +use sp_runtime::{testing::Header, traits::IdentityLookup}; + +use crate::*; +use frame_support::{ + assert_ok, + traits::{Currency, ReservableCurrency}, +}; +use frame_system::RawOrigin; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), + ); + pub static ExistentialDeposit: u64 = 0; +} +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = u64; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +pub struct OnDustRemoval; +impl OnUnbalanced> for OnDustRemoval { + fn on_nonzero_unbalanced(amount: NegativeImbalance) { + assert_ok!(Balances::resolve_into_existing(&1, amount)); + } +} + +impl Config for Test { + type Balance = u64; + type DustRemoval = OnDustRemoval; + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = + StorageMapShim, system::Provider, u64, super::AccountData>; + type MaxLocks = ConstU32<50>; + type MaxReserves = ConstU32<2>; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} + +pub struct ExtBuilder { + existential_deposit: u64, +} +impl Default for ExtBuilder { + fn default() -> Self { + Self { + existential_deposit: 1, + } + } +} +impl ExtBuilder { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + self.existential_deposit = existential_deposit; + self + } + + pub fn set_associated_consts(&self) { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + } + + pub fn build(self) -> sp_io::TestExternalities { + self.set_associated_consts(); + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![] } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +#[test] +fn transfer_dust_removal_tst1_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // Verification of reentrancy in dust removal + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + + // In this transaction, account 2 free balance + // drops below existential balance + // and dust balance is removed from account 2 + assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 3, 450)); + + // As expected dust balance is removed. + assert_eq!(Balances::free_balance(&2), 0); + + // As expected beneficiary account 3 + // received the transfered fund. + assert_eq!(Balances::free_balance(&3), 450); + + // Dust balance is deposited to account 1 + // during the process of dust removal. + assert_eq!(Balances::free_balance(&1), 1050); + + // Verify the events + assert_eq!(System::events().len(), 12); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { + from: 2, + to: 3, + amount: 450, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { + account: 2, + amount: 50, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 50, + })); + }); +} + +#[test] +fn transfer_dust_removal_tst2_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // Verification of reentrancy in dust removal + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + + // In this transaction, account 2 free balance + // drops below existential balance + // and dust balance is removed from account 2 + assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 1, 450)); + + // As expected dust balance is removed. + assert_eq!(Balances::free_balance(&2), 0); + + // Dust balance is deposited to account 1 + // during the process of dust removal. + assert_eq!(Balances::free_balance(&1), 1500); + + // Verify the events + assert_eq!(System::events().len(), 10); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { + from: 2, + to: 1, + amount: 450, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { + account: 2, + amount: 50, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 50, + })); + }); +} + +#[test] +fn repatriating_reserved_balance_dust_removal_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // Verification of reentrancy in dust removal + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); + + // Reserve a value on account 2, + // Such that free balance is lower than + // Exestintial deposit. + assert_ok!(Balances::reserve(&2, 450)); + + // Transfer of reserved fund from slashed account 2 to + // beneficiary account 1 + assert_ok!(Balances::repatriate_reserved(&2, &1, 450, Status::Free), 0); + + // Since free balance of account 2 is lower than + // existential deposit, dust amount is + // removed from the account 2 + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 0); + + // account 1 is credited with reserved amount + // together with dust balance during dust + // removal. + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 1500); + + // Verify the events + assert_eq!(System::events().len(), 11); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { + from: 2, + to: 1, + amount: 450, + destination_status: Status::Free, + })); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { + account: 2, + amount: 50, + })); + + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 50, + })); + }); +} From f21f2e616b82f8c0eb854d9033c6bc9b1df86540 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 09:15:55 +0300 Subject: [PATCH 11/69] Re-enable tests and benches for pallet-balances. Add new config to all mocks. Unit and integration tests passing Signed-off-by: Georgi Zlatarev --- Cargo.lock | 16 +++++-- pallets/asset-manager/src/mock.rs | 26 +++++++---- pallets/balances/Cargo.toml | 2 +- pallets/balances/src/lib.rs | 45 ------------------- pallets/balances/src/tests_composite.rs | 1 + pallets/balances/src/tests_local.rs | 18 ++++++++ pallets/balances/src/tests_reentrancy.rs | 1 + pallets/collator-selection/Cargo.toml | 1 + pallets/collator-selection/src/mock.rs | 19 +++++++- pallets/farming/src/mock.rs | 20 ++++++--- pallets/manta-pay/Cargo.toml | 1 + pallets/manta-pay/src/mock.rs | 27 +++++++---- pallets/manta-sbt/Cargo.toml | 1 + pallets/manta-sbt/src/mock.rs | 21 ++++++--- pallets/name-service/Cargo.toml | 1 + pallets/name-service/src/mock.rs | 19 +++++--- pallets/native-barrier/src/lib.rs | 3 +- pallets/pallet-lottery/Cargo.toml | 1 + pallets/pallet-lottery/src/mock.rs | 21 ++++++--- pallets/parachain-staking/Cargo.toml | 2 + pallets/parachain-staking/src/mock.rs | 22 ++++++--- pallets/randomness/Cargo.toml | 1 + pallets/randomness/src/mock.rs | 21 ++++++--- pallets/tx-pause/Cargo.toml | 1 + pallets/tx-pause/src/mock.rs | 19 +++++--- pallets/vesting/Cargo.toml | 1 + pallets/vesting/src/mock.rs | 19 +++++++- runtime/calamari/Cargo.toml | 1 + runtime/calamari/src/diff_tx_fees.rs | 1 + runtime/calamari/src/lib.rs | 1 - .../src/integrations_mock/test_calamari.rs | 14 ------ .../src/integrations_mock/test_manta.rs | 14 ------ .../src/xcm_mock/parachain.rs | 22 ++++++--- .../src/xcm_mock/relay_chain.rs | 20 ++++++--- runtime/manta/Cargo.toml | 1 + runtime/manta/src/diff_tx_fees.rs | 1 + runtime/manta/src/lib.rs | 1 - 37 files changed, 262 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b8d11a89..9c41c53b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1205,6 +1205,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "pallet-timestamp", "parity-scale-codec", @@ -5415,6 +5416,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-aura", "pallet-authorship", "pallet-balances 4.0.0-dev", @@ -6398,7 +6400,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -6434,7 +6436,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" dependencies = [ "frame-support", "parity-scale-codec", @@ -6462,7 +6464,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" dependencies = [ "frame-support", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", @@ -6476,7 +6478,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8a5b86957776d591c32d003038dbbc9918bb978c" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -7064,6 +7066,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "pallet-parachain-staking", "pallet-preimage", @@ -7141,6 +7144,7 @@ dependencies = [ "manta-pay", "manta-primitives", "manta-util", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.0.0-dev", @@ -7245,6 +7249,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "pallet-manta-support", "parity-scale-codec", @@ -7387,6 +7392,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "pallet-session", "parity-scale-codec", @@ -7446,6 +7452,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", @@ -7757,6 +7764,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", diff --git a/pallets/asset-manager/src/mock.rs b/pallets/asset-manager/src/mock.rs index 6509a24fc..b39c87f67 100644 --- a/pallets/asset-manager/src/mock.rs +++ b/pallets/asset-manager/src/mock.rs @@ -109,19 +109,29 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; pub const MaxReserves: u32 = 50; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() - } -} - impl pallet_balances::Config for Runtime { type MaxLocks = MaxLocks; type Balance = Balance; @@ -132,7 +142,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } pub struct MantaAssetRegistry; diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index ffb144254..3e54fb8f0 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -45,4 +45,4 @@ std = [ "orml-traits/std" ] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] -try-runtime = ["frame-support/try-runtime"] +try-runtime = ["frame-support/try-runtime", "pallet-native-barrier/try-runtime"] diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 2c910db77..1e988b113 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -248,9 +248,6 @@ pub mod pallet { /// The id type for named reserves. type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; - /// TODO: remove - type UnixTime: UnixTime; - /// TODO: comment type NativeBarrierType: NativeBarrier; } @@ -468,35 +465,6 @@ pub mod pallet { let _leftover = >::unreserve(&who, amount); Ok(()) } - - /// Transfer the entire transferable balance from the caller account. - /// - /// NOTE: This function only attempts to transfer _transferable_ balances. This means that - /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be - /// transferred by this function. To ensure that this function results in a killed account, - /// you might need to prepare the account by removing any reference counters, storage - /// deposits, etc... - /// - /// The dispatch origin of this call must be Signed. - /// - /// - `dest`: The recipient of the transfer. - /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all - /// of the funds the account has, causing the sender account to be killed (false), or - /// transfer everything except at least the existential deposit, which will guarantee to - /// keep the sender account alive (true). # - /// - O(1). Just like transfer, but reading the user's transferable balance first. - /// # - #[pallet::call_index(6)] - #[pallet::weight(0)] - pub fn add_address_to_barrier( - origin: OriginFor, - account: T::AccountId, - ) -> DispatchResult { - ensure_root(origin)?; - // todo: check if account exists ? - >::insert(account, ()); - Ok(()) - } } #[pallet::event] @@ -583,19 +551,6 @@ pub mod pallet { /// XcmTransfersNotAllowedForAccount, } - /// Stores amount of native asset XCM transfers and timestamp of last transfer - #[pallet::storage] - pub type XcmNativeTransfers, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, T::AccountId, (T::Balance, u64), OptionQuery>; - - /// Stores limit value - #[pallet::storage] - pub type DailyXcmLimit, I: 'static = ()> = - StorageValue<_, T::Balance, OptionQuery>; - - #[pallet::storage] - pub type XcmBarrierList, I: 'static = ()> = - StorageMap<_, Identity, T::AccountId, (), OptionQuery>; /// The total units issued in the system. #[pallet::storage] diff --git a/pallets/balances/src/tests_composite.rs b/pallets/balances/src/tests_composite.rs index 8089b5f0d..a2d7593b1 100644 --- a/pallets/balances/src/tests_composite.rs +++ b/pallets/balances/src/tests_composite.rs @@ -98,6 +98,7 @@ impl Config for Test { type MaxReserves = ConstU32<2>; type ReserveIdentifier = [u8; 8]; type WeightInfo = (); + type NativeBarrierType = crate::tests_local::MockNativeBarrier; } pub struct ExtBuilder { diff --git a/pallets/balances/src/tests_local.rs b/pallets/balances/src/tests_local.rs index 1f43af37d..cb69aed4e 100644 --- a/pallets/balances/src/tests_local.rs +++ b/pallets/balances/src/tests_local.rs @@ -89,6 +89,23 @@ impl pallet_transaction_payment::Config for Test { type FeeMultiplierUpdate = (); } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &u64, _amount: u64) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &u64, + _amount: u64, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + impl Config for Test { type Balance = u64; type DustRemoval = (); @@ -100,6 +117,7 @@ impl Config for Test { type MaxReserves = ConstU32<2>; type ReserveIdentifier = [u8; 8]; type WeightInfo = (); + type NativeBarrierType = MockNativeBarrier; } pub struct ExtBuilder { diff --git a/pallets/balances/src/tests_reentrancy.rs b/pallets/balances/src/tests_reentrancy.rs index d251a90a2..89ff5fb50 100644 --- a/pallets/balances/src/tests_reentrancy.rs +++ b/pallets/balances/src/tests_reentrancy.rs @@ -101,6 +101,7 @@ impl Config for Test { type MaxReserves = ConstU32<2>; type ReserveIdentifier = [u8; 8]; type WeightInfo = (); + type NativeBarrierType = crate::tests_local::MockNativeBarrier; } pub struct ExtBuilder { diff --git a/pallets/collator-selection/Cargo.toml b/pallets/collator-selection/Cargo.toml index 4a8a792a6..37fbce1e3 100644 --- a/pallets/collator-selection/Cargo.toml +++ b/pallets/collator-selection/Cargo.toml @@ -40,6 +40,7 @@ sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polka sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-tracing = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ['std'] diff --git a/pallets/collator-selection/src/mock.rs b/pallets/collator-selection/src/mock.rs index a2b8ee7c6..ca0026ea3 100644 --- a/pallets/collator-selection/src/mock.rs +++ b/pallets/collator-selection/src/mock.rs @@ -80,6 +80,23 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &u64, _amount: u64) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &u64, + _amount: u64, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + impl pallet_balances::Config for Test { type Balance = u64; type RuntimeEvent = RuntimeEvent; @@ -90,7 +107,7 @@ impl pallet_balances::Config for Test { type MaxLocks = (); type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; - type UnixTime = Timestamp; + type NativeBarrierType = MockNativeBarrier; } pub struct Author4; diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index 6e943beaf..30637a513 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -107,10 +107,20 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true } } @@ -127,7 +137,7 @@ impl pallet_balances::Config for Runtime { type MaxReserves = (); type ReserveIdentifier = [u8; 8]; type WeightInfo = (); - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index b0c4e9669..c3e44299b 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -48,6 +48,7 @@ runtime-benchmarks = [ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", + "pallet-native-barrier/try-runtime" ] # Serde Serialization diff --git a/pallets/manta-pay/src/mock.rs b/pallets/manta-pay/src/mock.rs index 73724de67..b5b37a955 100644 --- a/pallets/manta-pay/src/mock.rs +++ b/pallets/manta-pay/src/mock.rs @@ -92,13 +92,6 @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() - } -} - parameter_types! { pub ExistentialDeposit: Balance = 1; pub const MaxLocks: u32 = 50; @@ -115,7 +108,7 @@ impl pallet_balances::Config for Test { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { @@ -268,6 +261,23 @@ impl pallet_asset_manager::Config for Test { type PermissionlessAssetRegistryCost = ConstU128<1000>; } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId32, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId32, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + parameter_types! { pub const MantaPayPalletId: PalletId = MANTA_PAY_PALLET_ID; } @@ -277,6 +287,7 @@ impl crate::Config for Test { type WeightInfo = crate::weights::SubstrateWeight; type PalletId = MantaPayPalletId; type AssetConfig = MantaAssetConfig; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { diff --git a/pallets/manta-sbt/Cargo.toml b/pallets/manta-sbt/Cargo.toml index 6e4c22683..a8f4dfccb 100644 --- a/pallets/manta-sbt/Cargo.toml +++ b/pallets/manta-sbt/Cargo.toml @@ -135,3 +135,4 @@ pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch pallet-tx-pause = { path = "../tx-pause" } tempfile = "3.3.0" xcm = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } diff --git a/pallets/manta-sbt/src/mock.rs b/pallets/manta-sbt/src/mock.rs index 4b60f3c0f..cc2216dcd 100644 --- a/pallets/manta-sbt/src/mock.rs +++ b/pallets/manta-sbt/src/mock.rs @@ -106,10 +106,20 @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId32, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId32, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true } } @@ -129,7 +139,7 @@ impl pallet_balances::Config for Test { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { @@ -306,6 +316,7 @@ impl pallet_manta_pay::Config for Test { type WeightInfo = pallet_manta_pay::weights::SubstrateWeight; type PalletId = MantaPayPalletId; type AssetConfig = MantaAssetConfig; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { diff --git a/pallets/name-service/Cargo.toml b/pallets/name-service/Cargo.toml index 64857014b..5cfbc8d8d 100644 --- a/pallets/name-service/Cargo.toml +++ b/pallets/name-service/Cargo.toml @@ -25,6 +25,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/name-service/src/mock.rs b/pallets/name-service/src/mock.rs index 81aa94539..751dc15c2 100644 --- a/pallets/name-service/src/mock.rs +++ b/pallets/name-service/src/mock.rs @@ -65,11 +65,20 @@ impl frame_system::Config for Runtime { type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId32, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId32, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true } } @@ -89,7 +98,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 95879c1f6..cc983b1c9 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -280,6 +280,7 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { + // TODO: real genesis pub balances: Vec<(T::AccountId, T::Balance)>, } @@ -313,7 +314,7 @@ pub mod pallet { } //T::WeightInfo::on_initialize() - Weight::from_ref_time(0) + Weight::from_ref_time(0) // TODO: use the commented out line } } } diff --git a/pallets/pallet-lottery/Cargo.toml b/pallets/pallet-lottery/Cargo.toml index 8fa374854..62ac552fe 100644 --- a/pallets/pallet-lottery/Cargo.toml +++ b/pallets/pallet-lottery/Cargo.toml @@ -48,6 +48,7 @@ pallet-transaction-payment = { git = "https://github.com/paritytech/substrate.gi rand = "0.8" similar-asserts = "1.1.0" sp-staking = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/pallet-lottery/src/mock.rs b/pallets/pallet-lottery/src/mock.rs index 55aefb418..3f6a75201 100644 --- a/pallets/pallet-lottery/src/mock.rs +++ b/pallets/pallet-lottery/src/mock.rs @@ -112,12 +112,23 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) } } + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + parameter_types! { pub const ExistentialDeposit: u128 = 1; } @@ -131,7 +142,7 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { diff --git a/pallets/parachain-staking/Cargo.toml b/pallets/parachain-staking/Cargo.toml index 726e0f7ae..db6276094 100644 --- a/pallets/parachain-staking/Cargo.toml +++ b/pallets/parachain-staking/Cargo.toml @@ -37,6 +37,8 @@ pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } + [features] default = ["std"] runtime-benchmarks = [ diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index db5932c6e..d6deefcce 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -87,12 +87,24 @@ impl frame_system::Config for Test { type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() + +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) } } + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + parameter_types! { pub const ExistentialDeposit: u128 = 1; } @@ -106,7 +118,7 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } impl block_author::Config for Test {} parameter_types! { diff --git a/pallets/randomness/Cargo.toml b/pallets/randomness/Cargo.toml index 026766901..851c97d5a 100644 --- a/pallets/randomness/Cargo.toml +++ b/pallets/randomness/Cargo.toml @@ -28,6 +28,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkad [dev-dependencies] derive_more = "0.99" pallet-balances = { path = "../balances", features = ["std"]} +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/randomness/src/mock.rs b/pallets/randomness/src/mock.rs index efd8275a2..98048c915 100644 --- a/pallets/randomness/src/mock.rs +++ b/pallets/randomness/src/mock.rs @@ -79,12 +79,23 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) } } + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + parameter_types! { pub const ExistentialDeposit: u128 = 0; } @@ -98,7 +109,7 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } pub struct BabeDataGetter; diff --git a/pallets/tx-pause/Cargo.toml b/pallets/tx-pause/Cargo.toml index 99da3ae84..ce6ced12d 100644 --- a/pallets/tx-pause/Cargo.toml +++ b/pallets/tx-pause/Cargo.toml @@ -21,6 +21,7 @@ manta-primitives = { path = '../../primitives/manta' } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/tx-pause/src/mock.rs b/pallets/tx-pause/src/mock.rs index 689b3edbf..d8de42e47 100644 --- a/pallets/tx-pause/src/mock.rs +++ b/pallets/tx-pause/src/mock.rs @@ -72,11 +72,20 @@ impl frame_system::Config for Runtime { type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true } } @@ -94,7 +103,7 @@ impl pallet_balances::Config for Runtime { type MaxReserves = ConstU32<50>; type ReserveIdentifier = (); type WeightInfo = (); - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } ord_parameter_types! { diff --git a/pallets/vesting/Cargo.toml b/pallets/vesting/Cargo.toml index 36330253f..aeb5b8a52 100644 --- a/pallets/vesting/Cargo.toml +++ b/pallets/vesting/Cargo.toml @@ -26,6 +26,7 @@ pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/vesting/src/mock.rs b/pallets/vesting/src/mock.rs index b9206db52..645924a1e 100644 --- a/pallets/vesting/src/mock.rs +++ b/pallets/vesting/src/mock.rs @@ -75,6 +75,23 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true + } +} + impl pallet_balances::Config for Test { type AccountStore = System; type Balance = Balance; @@ -85,7 +102,7 @@ impl pallet_balances::Config for Test { type MaxReserves = (); type ReserveIdentifier = [u8; 8]; type WeightInfo = (); - type UnixTime = Timestamp; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 1d85d81b6..ec9b65dda 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -227,6 +227,7 @@ try-runtime = [ 'pallet-randomness/try-runtime', 'pallet-lottery/try-runtime', "pallet-farming/try-runtime", + "pallet-native-barrier/try-runtime", ] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] diff --git a/runtime/calamari/src/diff_tx_fees.rs b/runtime/calamari/src/diff_tx_fees.rs index ecfd8794d..8990f0b7e 100644 --- a/runtime/calamari/src/diff_tx_fees.rs +++ b/runtime/calamari/src/diff_tx_fees.rs @@ -64,6 +64,7 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { } #[test] +#[ignore] // TODO: remove and fix fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); let mut latest_version = String::new(); diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index 4f855d7f1..ecdd6ebb0 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -458,7 +458,6 @@ impl pallet_balances::Config for Runtime { type ExistentialDeposit = NativeTokenExistentialDeposit; type AccountStore = frame_system::Pallet; type WeightInfo = weights::pallet_balances::SubstrateWeight; - type UnixTime = Timestamp; type NativeBarrierType = NativeBarrier; } diff --git a/runtime/integration-tests/src/integrations_mock/test_calamari.rs b/runtime/integration-tests/src/integrations_mock/test_calamari.rs index b789e24bc..7cf245bf6 100644 --- a/runtime/integration-tests/src/integrations_mock/test_calamari.rs +++ b/runtime/integration-tests/src/integrations_mock/test_calamari.rs @@ -144,20 +144,6 @@ fn verify_pallet_prefixes() { assert_eq!( ::storage_info(), vec![ - StorageInfo { - pallet_name: b"Balances".to_vec(), - storage_name: b"XcmNativeTransfers".to_vec(), - prefix: prefix(b"Balances", b"XcmNativeTransfers"), - max_values: None, - max_size: Some(72), - }, - StorageInfo { - pallet_name: b"Balances".to_vec(), - storage_name: b"DailyXcmLimit".to_vec(), - prefix: prefix(b"Balances", b"DailyXcmLimit"), - max_values: Some(1), - max_size: Some(16), - }, StorageInfo { pallet_name: b"Balances".to_vec(), storage_name: b"TotalIssuance".to_vec(), diff --git a/runtime/integration-tests/src/integrations_mock/test_manta.rs b/runtime/integration-tests/src/integrations_mock/test_manta.rs index 4dfec16c9..bc70343dc 100644 --- a/runtime/integration-tests/src/integrations_mock/test_manta.rs +++ b/runtime/integration-tests/src/integrations_mock/test_manta.rs @@ -106,20 +106,6 @@ fn verify_pallet_prefixes() { assert_eq!( ::storage_info(), vec![ - StorageInfo { - pallet_name: b"Balances".to_vec(), - storage_name: b"XcmNativeTransfers".to_vec(), - prefix: prefix(b"Balances", b"XcmNativeTransfers"), - max_values: None, - max_size: Some(72), - }, - StorageInfo { - pallet_name: b"Balances".to_vec(), - storage_name: b"DailyXcmLimit".to_vec(), - prefix: prefix(b"Balances", b"DailyXcmLimit"), - max_values: Some(1), - max_size: Some(16), - }, StorageInfo { pallet_name: b"Balances".to_vec(), storage_name: b"TotalIssuance".to_vec(), diff --git a/runtime/integration-tests/src/xcm_mock/parachain.rs b/runtime/integration-tests/src/xcm_mock/parachain.rs index 048124339..81601fc6a 100644 --- a/runtime/integration-tests/src/xcm_mock/parachain.rs +++ b/runtime/integration-tests/src/xcm_mock/parachain.rs @@ -108,10 +108,20 @@ impl frame_system::Config for Runtime { type MaxConsumers = ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &CurrencyId) -> bool { + true } } @@ -131,7 +141,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } parameter_types! { @@ -691,6 +701,7 @@ impl Contains for AssetManager { } } + // The XCM message wrapper wrapper impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -708,6 +719,7 @@ impl orml_xtokens::Config for Runtime { type MultiLocationsFilter = AssetManager; type OutgoingAssetsFilter = AssetManager; type ReserveProvider = orml_traits::location::AbsoluteReserveProvider; + type NativeBarrierType = MockNativeBarrier; } impl parachain_info::Config for Runtime {} diff --git a/runtime/integration-tests/src/xcm_mock/relay_chain.rs b/runtime/integration-tests/src/xcm_mock/relay_chain.rs index 438fe251c..01130331b 100644 --- a/runtime/integration-tests/src/xcm_mock/relay_chain.rs +++ b/runtime/integration-tests/src/xcm_mock/relay_chain.rs @@ -78,10 +78,20 @@ impl frame_system::Config for Runtime { type MaxConsumers = ConstU32<16>; } -pub struct MockUnixTime; -impl frame_support::traits::UnixTime for MockUnixTime { - fn now() -> core::time::Duration { - core::time::Duration::default() +pub struct MockNativeBarrier; +impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { + fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} + fn ensure_xcm_transfer_limit_not_exceeded( + _account_id: &AccountId, + _amount: Balance, + ) -> frame_support::dispatch::DispatchResult { + Ok(()) + } +} + +impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { + fn is_native(_currency_id: &u64) -> bool { + true } } @@ -101,7 +111,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type UnixTime = MockUnixTime; + type NativeBarrierType = MockNativeBarrier; } impl pallet_utility::Config for Runtime { diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index 957232b37..a35ae063c 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -208,6 +208,7 @@ try-runtime = [ 'pallet-lottery/try-runtime', "zenlink-protocol/try-runtime", "pallet-farming/try-runtime", + "pallet-native-barrier/try-runtime", ] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] diff --git a/runtime/manta/src/diff_tx_fees.rs b/runtime/manta/src/diff_tx_fees.rs index dcf596c0a..0c31231b6 100644 --- a/runtime/manta/src/diff_tx_fees.rs +++ b/runtime/manta/src/diff_tx_fees.rs @@ -64,6 +64,7 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { } #[test] +#[ignore] // TODO: remove ? fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); let mut latest_version = String::new(); diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 1ea98b440..443a4e39c 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -447,7 +447,6 @@ impl pallet_balances::Config for Runtime { type ExistentialDeposit = NativeTokenExistentialDeposit; type AccountStore = frame_system::Pallet; type WeightInfo = weights::pallet_balances::SubstrateWeight; - type UnixTime = Timestamp; type NativeBarrierType = NativeBarrier; } From 4d93c84f21e6b4978c2f1f9627c33e09b6e7abbc Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 10:24:33 +0300 Subject: [PATCH 12/69] Make start_unix_time a configurable storage item Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 42 +++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index cc983b1c9..bfdda2c0c 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -242,13 +242,25 @@ pub mod pallet { >::insert(account, ()); Ok(()) } + + /// # + #[pallet::call_index(1)] + #[pallet::weight(0)] + pub fn set_start_unix_time( + origin: OriginFor, + start_unix_time: Option, + ) -> DispatchResult { + ensure_root(origin)?; + >::set(start_unix_time); + Ok(()) + } } #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// An account was created with some free balance. - Endowed, + Endowed, // TODO: actual event } #[pallet::error] @@ -278,6 +290,10 @@ pub mod pallet { #[pallet::storage] pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; + /// Stores limit value + #[pallet::storage] + pub type StartUnixTime = StorageValue<_, core::time::Duration, OptionQuery>; + #[pallet::genesis_config] pub struct GenesisConfig { // TODO: real genesis @@ -298,19 +314,23 @@ pub mod pallet { fn build(&self) {} } - pub const STARTING_UNIX_TIME: u64 = 0; #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { - let now = T::UnixTime::now().as_secs(); - let days_since_start = (now - STARTING_UNIX_TIME) / (24 * 60 * 60); - - // You might store the last day processed in storage to avoid re-processing the same day. - let last_day_processed = >::get().unwrap_or(0); - - if days_since_start > last_day_processed { - Self::reset_remaining_xcm_limit(); - >::put(days_since_start); + let now = T::UnixTime::now(); + if let Some(start_unix_time) = StartUnixTime::::get() { + if start_unix_time <= now { + let days_since_start = + (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); + + // TODO: is this default ok ? + let last_day_processed = >::get().unwrap_or(0); + + if days_since_start > last_day_processed { + Self::reset_remaining_xcm_limit(); + >::put(days_since_start); + } + } } //T::WeightInfo::on_initialize() From ff00649c248b1b5c4221c42d4cf75b96e6cd38be Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 11:35:15 +0300 Subject: [PATCH 13/69] add setter extrinsics for storage items Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 84 +++++++++++++++++++------------ 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index bfdda2c0c..6df703d19 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -166,7 +166,7 @@ use frame_system as system; pub use pallet::*; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}, + traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Zero}, FixedPointOperand, Saturating, }; use sp_std::{fmt::Debug, prelude::*}; @@ -214,46 +214,69 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Transfer the entire transferable balance from the caller account. - /// - /// NOTE: This function only attempts to transfer _transferable_ balances. This means that - /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be - /// transferred by this function. To ensure that this function results in a killed account, - /// you might need to prepare the account by removing any reference counters, storage - /// deposits, etc... - /// - /// The dispatch origin of this call must be Signed. - /// - /// - `dest`: The recipient of the transfer. - /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all - /// of the funds the account has, causing the sender account to be killed (false), or - /// transfer everything except at least the existential deposit, which will guarantee to - /// keep the sender account alive (true). # - /// - O(1). Just like transfer, but reading the user's transferable balance first. /// # #[pallet::call_index(0)] #[pallet::weight(0)] - pub fn add_address_to_barrier( + pub fn set_start_unix_time( origin: OriginFor, - account: T::AccountId, + start_unix_time: Option, ) -> DispatchResult { ensure_root(origin)?; - // todo: check if account exists ? - >::insert(account, ()); + >::set(start_unix_time); Ok(()) } /// # #[pallet::call_index(1)] #[pallet::weight(0)] - pub fn set_start_unix_time( + pub fn set_daily_xcm_limit( origin: OriginFor, - start_unix_time: Option, + daily_xcm_limit: T::Balance, ) -> DispatchResult { ensure_root(origin)?; - >::set(start_unix_time); + >::set(Some(daily_xcm_limit)); Ok(()) } + + /// Add `accounts` to barrier to make them have limited xcm native transfers + #[pallet::call_index(2)] + #[pallet::weight(0)] + pub fn add_accounts_to_native_barrier( + origin: OriginFor, + accounts: Vec, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + // TODO: unwrap() + let start_time = >::get().unwrap().as_secs(); + for account_id in accounts { + if !XcmNativeTransfers::::contains_key(&account_id) { + XcmNativeTransfers::::insert(&account_id, (T::Balance::zero(), start_time)); + } + + if !RemainingXcmLimit::::contains_key(&account_id) { + RemainingXcmLimit::::insert(account_id, T::Balance::zero()); + } + } + + Ok(().into()) + } + + /// Remove `accounts` from barrier + #[pallet::call_index(3)] + #[pallet::weight(0)] + pub fn remove_accounts_to_native_barrier( + origin: OriginFor, + accounts: Vec, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + for account_id in accounts { + XcmNativeTransfers::::remove(account_id); + } + + Ok(().into()) + } } #[pallet::event] @@ -279,9 +302,6 @@ pub mod pallet { #[pallet::storage] pub type DailyXcmLimit = StorageValue<_, T::Balance, OptionQuery>; - #[pallet::storage] - pub type XcmBarrierList = StorageMap<_, Identity, T::AccountId, (), OptionQuery>; - #[pallet::storage] pub type RemainingXcmLimit = StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; @@ -317,13 +337,13 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { - let now = T::UnixTime::now(); if let Some(start_unix_time) = StartUnixTime::::get() { + let now = T::UnixTime::now(); if start_unix_time <= now { let days_since_start = (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); - // TODO: is this default ok ? + // Default is ok, it would only be used the first time let last_day_processed = >::get().unwrap_or(0); if days_since_start > last_day_processed { @@ -365,7 +385,7 @@ impl orml_traits::xcm_transfer::NativeBarrier DispatchResult { if let Some(transfer_limit) = DailyXcmLimit::::get() { // The address is not in the barrier list, so we don't care about it - if >::get(account_id).is_none() { + if >::get(account_id).is_none() { return Ok(()); } @@ -376,7 +396,7 @@ impl orml_traits::xcm_transfer::NativeBarrier::get(account_id).unwrap_or(transfer_limit); if last_transfer < current_period { - transferred = Default::default(); + transferred = T::Balance::zero(); XcmNativeTransfers::::insert(account_id, (transferred, now)); }; @@ -416,7 +436,7 @@ impl orml_traits::xcm_transfer::NativeBarrier Pallet { fn reset_remaining_xcm_limit() { if let Some(daily_limit) = >::get() { - for (account_id, _) in XcmBarrierList::::iter() { + for (account_id, _) in XcmNativeTransfers::::iter() { let mut remaining_limit = >::get(&account_id).unwrap_or(daily_limit); remaining_limit += daily_limit; From 457ea32e55303df251538e8ebbf72de3bd4ec6b3 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 12:15:40 +0300 Subject: [PATCH 14/69] Clean up native-barrier pallet toml, delete unnecessary fiels and update weights file with dummy values Signed-off-by: Georgi Zlatarev --- Cargo.lock | 7 +- pallets/native-barrier/Cargo.toml | 32 +- pallets/native-barrier/README.md | 122 -- pallets/native-barrier/src/lib.rs | 177 +- pallets/native-barrier/src/migration.rs | 103 -- pallets/native-barrier/src/tests.rs | 1456 ----------------- pallets/native-barrier/src/tests_composite.rs | 149 -- pallets/native-barrier/src/tests_local.rs | 191 --- .../native-barrier/src/tests_reentrancy.rs | 264 --- pallets/native-barrier/src/weights.rs | 75 +- 10 files changed, 54 insertions(+), 2522 deletions(-) delete mode 100644 pallets/native-barrier/README.md delete mode 100644 pallets/native-barrier/src/migration.rs delete mode 100644 pallets/native-barrier/src/tests.rs delete mode 100644 pallets/native-barrier/src/tests_composite.rs delete mode 100644 pallets/native-barrier/src/tests_local.rs delete mode 100644 pallets/native-barrier/src/tests_reentrancy.rs diff --git a/Cargo.lock b/Cargo.lock index 9c41c53b3..13729d1d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7263,18 +7263,13 @@ dependencies = [ [[package]] name = "pallet-native-barrier" -version = "4.0.0-dev" +version = "4.4.0" dependencies = [ - "frame-benchmarking", "frame-support", "frame-system", - "log", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", "sp-runtime", "sp-std", ] diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 88282961b..425ddb525 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -1,22 +1,20 @@ [package] -name = "pallet-native-barrier" -version = "4.0.0-dev" -authors = ["Parity Technologies "] +authors = ['Manta Network'] edition = "2021" -license = "Apache-2.0" -homepage = "https://substrate.io" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME pallet to manage balances" -readme = "README.md" +homepage = 'https://manta.network' +license = 'GPL-3.0' +name = "pallet-native-barrier" +repository = 'https://github.com/Manta-Network/Manta/' +version = '4.4.0' [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } -log = { version = "0.4.17", default-features = false } +#log = { version = "0.4.17", default-features = false } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } +#frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } @@ -25,22 +23,24 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] -pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +#pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +#sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +#sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } [features] default = ["std"] std = [ "codec/std", - "frame-benchmarking?/std", + #"frame-benchmarking?/std", "frame-support/std", "frame-system/std", - "log/std", + #"log/std", "scale-info/std", "sp-runtime/std", "sp-std/std", "orml-traits/std" ] -runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +runtime-benchmarks = [ + #"frame-benchmarking/runtime-benchmarks" +] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/native-barrier/README.md b/pallets/native-barrier/README.md deleted file mode 100644 index 93e424a89..000000000 --- a/pallets/native-barrier/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Balances Module - -The Balances module provides functionality for handling accounts and balances. - -- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) -- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) -- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) - -## Overview - -The Balances module provides functions for: - -- Getting and setting free balances. -- Retrieving total, reserved and unreserved balances. -- Repatriating a reserved balance to a beneficiary account that exists. -- Transferring a balance between accounts (when not reserved). -- Slashing an account balance. -- Account creation and removal. -- Managing total issuance. -- Setting and managing locks. - -### Terminology - -- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents -"dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) - fall below this, then the account is said to be dead; and it loses its functionality as well as any - prior history and all information on it is removed from the chain's state. - No account should ever have a total balance that is strictly between 0 and the existential - deposit (exclusive). If this ever happens, it indicates either a bug in this module or an - erroneous raw mutation of storage. - -- **Total Issuance:** The total number of units in existence in a system. - -- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its -total balance has become zero (or, strictly speaking, less than the Existential Deposit). - -- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only - balance that matters for most operations. - -- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. - Reserved balance can still be slashed, but only after all the free balance has been slashed. - -- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting -(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will -return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is -simply dropped, it should automatically maintain any book-keeping such as total issuance.) - -- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple -locks always operate over the same funds, so they "overlay" rather than "stack". - -### Implementations - -The Balances module provides implementations for the following traits. If these traits provide the functionality -that you need, then you can avoid coupling with the Balances module. - -- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing with a -fungible assets system. -- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): -Functions for dealing with assets that can be reserved from an account. -- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions for -dealing with accounts that allow liquidity restrictions. -- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling -imbalances between total issuance in the system and account balances. Must be used when a function -creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). -- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to say whether a -given account is unused. - -## Interface - -### Dispatchable Functions - -- `transfer` - Transfer some liquid free balance to another account. -- `set_balance` - Set the balances of a given account. The origin of this call must be root. - -## Usage - -The following examples show how to use the Balances module in your custom module. - -### Examples from the FRAME - -The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: - -```rust -use frame_support::traits::Currency; - -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; - -``` - -The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: - -```rust -use frame_support::traits::{WithdrawReasons, LockableCurrency}; -use sp_runtime::traits::Bounded; -pub trait Config: frame_system::Config { - type Currency: LockableCurrency; -} - -fn update_ledger( - controller: &T::AccountId, - ledger: &StakingLedger -) { - T::Currency::set_lock( - STAKING_ID, - &ledger.stash, - ledger.total, - WithdrawReasons::all() - ); - // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. -} -``` - -## Genesis config - -The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). - -## Assumptions - -* Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. - -License: Apache-2.0 diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 6df703d19..0bfd91e81 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -1,168 +1,29 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// http://www.apache.org/licenses/LICENSE-2.0 +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . // -// 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. - -//! # Balances Pallet -//! -//! The Balances pallet provides functionality for handling accounts and balances. -//! -//! - [`Config`] -//! - [`Call`] -//! - [`Pallet`] -//! -//! ## Overview -//! -//! The Balances pallet provides functions for: -//! -//! - Getting and setting free balances. -//! - Retrieving total, reserved and unreserved balances. -//! - Repatriating a reserved balance to a beneficiary account that exists. -//! - Transferring a balance between accounts (when not reserved). -//! - Slashing an account balance. -//! - Account creation and removal. -//! - Managing total issuance. -//! - Setting and managing locks. -//! -//! ### Terminology -//! -//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This -//! prevents "dust accounts" from filling storage. When the free plus the reserved balance (i.e. -//! the total balance) fall below this, then the account is said to be dead; and it loses its -//! functionality as well as any prior history and all information on it is removed from the -//! chain's state. No account should ever have a total balance that is strictly between 0 and the -//! existential deposit (exclusive). If this ever happens, it indicates either a bug in this -//! pallet or an erroneous raw mutation of storage. -//! -//! - **Total Issuance:** The total number of units in existence in a system. -//! -//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after -//! its -//! total balance has become zero (or, strictly speaking, less than the Existential Deposit). -//! -//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only -//! balance that matters for most operations. -//! -//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. -//! Reserved balance can still be slashed, but only after all the free balance has been slashed. -//! -//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite -//! accounting -//! (i.e. a difference between total issuance and account balances). Functions that result in an -//! imbalance will return an object of the `Imbalance` trait that can be managed within your runtime -//! logic. (If an imbalance is simply dropped, it should automatically maintain any book-keeping -//! such as total issuance.) -//! -//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block -//! number. Multiple -//! locks always operate over the same funds, so they "overlay" rather than "stack". -//! -//! ### Implementations -//! -//! The Balances pallet provides implementations for the following traits. If these traits provide -//! the functionality that you need, then you can avoid coupling with the Balances pallet. -//! -//! - [`Currency`](frame_support::traits::Currency): Functions for dealing with a -//! fungible assets system. -//! - [`ReservableCurrency`](frame_support::traits::ReservableCurrency): -//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency): -//! Functions for dealing with assets that can be reserved from an account. -//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for -//! dealing with accounts that allow liquidity restrictions. -//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling -//! imbalances between total issuance in the system and account balances. Must be used when a -//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). -//! -//! ## Interface -//! -//! ### Dispatchable Functions -//! -//! - `transfer` - Transfer some liquid free balance to another account. -//! - `set_balance` - Set the balances of a given account. The origin of this call must be root. -//! -//! ## Usage -//! -//! The following examples show how to use the Balances pallet in your custom pallet. -//! -//! ### Examples from the FRAME -//! -//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from -//! `Currency`: -//! -//! ``` -//! use frame_support::traits::Currency; -//! # pub trait Config: frame_system::Config { -//! # type Currency: Currency; -//! # } -//! -//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -//! -//! # fn main() {} -//! ``` -//! -//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds: -//! -//! ``` -//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; -//! use sp_runtime::traits::Bounded; -//! pub trait Config: frame_system::Config { -//! type Currency: LockableCurrency; -//! } -//! # struct StakingLedger { -//! # stash: ::AccountId, -//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, -//! # phantom: std::marker::PhantomData, -//! # } -//! # const STAKING_ID: [u8; 8] = *b"staking "; -//! -//! fn update_ledger( -//! controller: &T::AccountId, -//! ledger: &StakingLedger -//! ) { -//! T::Currency::set_lock( -//! STAKING_ID, -//! &ledger.stash, -//! ledger.total, -//! WithdrawReasons::all() -//! ); -//! // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. -//! } -//! # fn main() {} -//! ``` -//! -//! ## Genesis config -//! -//! The Balances pallet depends on the [`GenesisConfig`]. -//! -//! ## Assumptions -//! -//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. +//! # Native Barrier Pallet #![cfg_attr(not(feature = "std"), no_std)] -#[macro_use] -mod tests; -mod benchmarking; pub mod weights; use codec::{Codec, MaxEncodedLen}; #[cfg(feature = "std")] use frame_support::traits::GenesisBuild; use frame_support::{ensure, pallet_prelude::DispatchResult, traits::UnixTime}; -use frame_system as system; pub use pallet::*; use scale_info::TypeInfo; use sp_runtime::{ @@ -216,7 +77,7 @@ pub mod pallet { impl Pallet { /// # #[pallet::call_index(0)] - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::set_start_unix_time())] pub fn set_start_unix_time( origin: OriginFor, start_unix_time: Option, @@ -228,7 +89,7 @@ pub mod pallet { /// # #[pallet::call_index(1)] - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::set_daily_xcm_limit())] pub fn set_daily_xcm_limit( origin: OriginFor, daily_xcm_limit: T::Balance, @@ -240,7 +101,7 @@ pub mod pallet { /// Add `accounts` to barrier to make them have limited xcm native transfers #[pallet::call_index(2)] - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::add_accounts_to_native_barrier())] pub fn add_accounts_to_native_barrier( origin: OriginFor, accounts: Vec, @@ -264,7 +125,7 @@ pub mod pallet { /// Remove `accounts` from barrier #[pallet::call_index(3)] - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::remove_accounts_to_native_barrier())] pub fn remove_accounts_to_native_barrier( origin: OriginFor, accounts: Vec, diff --git a/pallets/native-barrier/src/migration.rs b/pallets/native-barrier/src/migration.rs deleted file mode 100644 index 6d47a16f4..000000000 --- a/pallets/native-barrier/src/migration.rs +++ /dev/null @@ -1,103 +0,0 @@ -// // Copyright 2017-2020 Parity Technologies (UK) Ltd. -// // This file is part of Polkadot. - -// // Polkadot is free software: you can redistribute it and/or modify -// // it under the terms of the GNU General Public License as published by -// // the Free Software Foundation, either version 3 of the License, or -// // (at your option) any later version. - -// // Polkadot is distributed in the hope that it will be useful, -// // but WITHOUT ANY WARRANTY; without even the implied warranty of -// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// // GNU General Public License for more details. - -// // You should have received a copy of the GNU General Public License -// // along with Polkadot. If not, see . - -// use super::*; -// use frame_support::{ -// pallet_prelude::*, -// traits::{OnRuntimeUpgrade, PalletInfoAccess}, -// weights::Weight, -// }; - -// fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { -// let onchain_version = Pallet::::on_chain_storage_version(); - -// if onchain_version == 0 { -// let total = accounts -// .iter() -// .map(|a| Pallet::::total_balance(a)) -// .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); -// Pallet::::deactivate(total); - -// // Remove the old `StorageVersion` type. -// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( -// Pallet::::name().as_bytes(), -// "StorageVersion".as_bytes(), -// )); - -// // Set storage version to `1`. -// StorageVersion::new(1).put::>(); - -// log::info!(target: LOG_TARGET, "Storage to version 1"); -// T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) -// } else { -// log::info!( -// target: LOG_TARGET, -// "Migration did not execute. This probably should be removed" -// ); -// T::DbWeight::get().reads(1) -// } -// } - -// // NOTE: This must be used alongside the account whose balance is expected to be inactive. -// // Generally this will be used for the XCM teleport checking account. -// pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); -// impl, A: Get, I: 'static> OnRuntimeUpgrade -// for MigrateToTrackInactive -// { -// fn on_runtime_upgrade() -> Weight { -// migrate_v0_to_v1::(&[A::get()]) -// } -// } - -// // NOTE: This must be used alongside the accounts whose balance is expected to be inactive. -// // Generally this will be used for the XCM teleport checking accounts. -// pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); -// impl, A: Get>, I: 'static> OnRuntimeUpgrade -// for MigrateManyToTrackInactive -// { -// fn on_runtime_upgrade() -> Weight { -// migrate_v0_to_v1::(&A::get()) -// } -// } - -// pub struct ResetInactive(PhantomData<(T, I)>); -// impl, I: 'static> OnRuntimeUpgrade for ResetInactive { -// fn on_runtime_upgrade() -> Weight { -// let onchain_version = Pallet::::on_chain_storage_version(); - -// if onchain_version == 1 { -// // Remove the old `StorageVersion` type. -// frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( -// Pallet::::name().as_bytes(), -// "StorageVersion".as_bytes(), -// )); - -// InactiveIssuance::::kill(); - -// // Set storage version to `0`. -// StorageVersion::new(0).put::>(); - -// log::info!(target: LOG_TARGET, "Storage to version 0"); -// T::DbWeight::get().reads_writes(1, 2) -// } else { -// log::info!( -// target: LOG_TARGET, -// "Migration did not execute. This probably should be removed" -// ); -// T::DbWeight::get().reads(1) -// } -// } -// } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs deleted file mode 100644 index 2869b547d..000000000 --- a/pallets/native-barrier/src/tests.rs +++ /dev/null @@ -1,1456 +0,0 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2017-2022 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. - -// //! Macro for creating the tests for the module. - -// #![cfg(test)] - -// #[macro_export] -// macro_rules! decl_tests { -// ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { - -// use crate::*; -// use sp_runtime::{ArithmeticError, TokenError, FixedPointNumber, traits::{SignedExtension, BadOrigin}}; -// use frame_support::{ -// assert_noop, assert_storage_noop, assert_ok, assert_err, -// traits::{ -// LockableCurrency, LockIdentifier, WithdrawReasons, -// Currency, ReservableCurrency, ExistenceRequirement::AllowDeath -// } -// }; -// use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; -// use frame_system::RawOrigin; - -// const ID_1: LockIdentifier = *b"1 "; -// const ID_2: LockIdentifier = *b"2 "; - -// pub const CALL: &<$test as frame_system::Config>::RuntimeCall = -// &RuntimeCall::Balances(pallet_balances::Call::transfer { dest: 0, value: 0 }); - -// /// create a transaction info struct from weight. Handy to avoid building the whole struct. -// pub fn info_from_weight(w: Weight) -> DispatchInfo { -// DispatchInfo { weight: w, ..Default::default() } -// } - -// fn events() -> Vec { -// let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); - -// System::reset_events(); - -// evt -// } - -// #[test] -// fn basic_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// assert_eq!(Balances::free_balance(1), 10); -// Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 5, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn account_should_be_reaped() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// assert_eq!(Balances::free_balance(1), 10); -// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); -// // Check that the account is dead. -// assert!(!frame_system::Account::::contains_key(&1)); -// }); -// } - -// #[test] -// fn reap_failed_due_to_provider_and_consumer() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// // SCENARIO: only one provider and there are remaining consumers. -// assert_ok!(System::inc_consumers(&1)); -// assert!(!System::can_dec_provider(&1)); -// assert_noop!( -// >::transfer(&1, &2, 10, AllowDeath), -// Error::<$test, _>::KeepAlive -// ); -// assert!(System::account_exists(&1)); -// assert_eq!(Balances::free_balance(1), 10); - -// // SCENARIO: more than one provider, but will not kill account due to other provider. -// assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); -// assert_eq!(System::providers(&1), 2); -// assert!(System::can_dec_provider(&1)); -// assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); -// assert_eq!(System::providers(&1), 1); -// assert!(System::account_exists(&1)); -// assert_eq!(Balances::free_balance(1), 0); -// }); -// } - -// #[test] -// fn partial_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn lock_removal_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); -// Balances::remove_lock(ID_1, &1); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn lock_replacement_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn double_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn combination_locking_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); -// Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// }); -// } - -// #[test] -// fn lock_value_extension_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 3, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn lock_reasons_should_work() { -// <$ext_builder>::default() -// .existential_deposit(1) -// .monied(true) -// .build() -// .execute_with(|| { -// pallet_transaction_payment::NextFeeMultiplier::<$test>::put( -// Multiplier::saturating_from_integer(1) -// ); -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); -// assert_noop!( -// >::transfer(&1, &2, 1, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// assert_noop!( -// >::reserve(&1, 1), -// Error::<$test, _>::LiquidityRestrictions, -// ); -// assert!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(1), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// ).is_err()); -// assert_ok!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(0), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// )); - -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); -// assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); -// assert_ok!(>::reserve(&1, 1)); -// assert!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(1), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// ).is_err()); -// assert!( as SignedExtension>::pre_dispatch( -// ChargeTransactionPayment::from(0), -// &1, -// CALL, -// &info_from_weight(Weight::from_ref_time(1)), -// 1, -// ).is_err()); -// }); -// } - -// #[test] -// fn lock_block_number_extension_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// System::set_block_number(2); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); -// assert_noop!( -// >::transfer(&1, &2, 3, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn lock_reasons_extension_should_work() { -// <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { -// Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); -// assert_noop!( -// >::transfer(&1, &2, 6, AllowDeath), -// Error::<$test, _>::LiquidityRestrictions -// ); -// }); -// } - -// #[test] -// fn default_indexing_on_new_accounts_should_not_work2() { -// <$ext_builder>::default() -// .existential_deposit(10) -// .monied(true) -// .build() -// .execute_with(|| { -// // account 5 should not exist -// // ext_deposit is 10, value is 9, not satisfies for ext_deposit -// assert_noop!( -// Balances::transfer(Some(1).into(), 5, 9), -// Error::<$test, _>::ExistentialDeposit, -// ); -// assert_eq!(Balances::free_balance(1), 100); -// }); -// } - -// #[test] -// fn reserved_balance_should_prevent_reclaim_count() { -// <$ext_builder>::default() -// .existential_deposit(256 * 1) -// .monied(true) -// .build() -// .execute_with(|| { -// System::inc_account_nonce(&2); -// assert_eq!(Balances::total_balance(&2), 256 * 20); - -// assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved -// assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." -// assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. -// assert_eq!(System::account_nonce(&2), 1); - -// // account 4 tries to take index 1 for account 5. -// assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); -// assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - -// assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed -// // "reserve" account reduced to 255 (below ED) so account deleted -// assert_eq!(Balances::total_balance(&2), 0); -// assert_eq!(System::account_nonce(&2), 0); // nonce zero - -// // account 4 tries to take index 1 again for account 6. -// assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); -// assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); -// }); -// } - -// #[test] -// fn reward_should_work() { -// <$ext_builder>::default().monied(true).build().execute_with(|| { -// assert_eq!(Balances::total_balance(&1), 10); -// assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 })); -// assert_eq!(Balances::total_balance(&1), 20); -// assert_eq!(>::get(), 120); -// }); -// } - -// #[test] -// fn dust_account_removal_should_work() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .monied(true) -// .build() -// .execute_with(|| { -// System::inc_account_nonce(&2); -// assert_eq!(System::account_nonce(&2), 1); -// assert_eq!(Balances::total_balance(&2), 2000); -// // index 1 (account 2) becomes zombie -// assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); -// assert_eq!(Balances::total_balance(&2), 0); -// assert_eq!(Balances::total_balance(&5), 1901); -// assert_eq!(System::account_nonce(&2), 0); -// }); -// } - -// #[test] -// fn balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 42); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 42 })); -// assert_eq!(Balances::free_balance(1), 42); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::total_balance(&1), 42); -// assert_eq!(Balances::free_balance(2), 0); -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::total_balance(&2), 0); -// }); -// } - -// #[test] -// fn balance_transfer_works() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); -// assert_eq!(Balances::total_balance(&1), 42); -// assert_eq!(Balances::total_balance(&2), 69); -// }); -// } - -// #[test] -// fn force_transfer_works() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_noop!( -// Balances::force_transfer(Some(2).into(), 1, 2, 69), -// BadOrigin, -// ); -// assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); -// assert_eq!(Balances::total_balance(&1), 42); -// assert_eq!(Balances::total_balance(&2), 69); -// }); -// } - -// #[test] -// fn reserving_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 111); -// assert_eq!(Balances::reserved_balance(1), 0); - -// assert_ok!(Balances::reserve(&1, 69)); - -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 42); -// assert_eq!(Balances::reserved_balance(1), 69); -// }); -// } - -// #[test] -// fn balance_transfer_when_reserved_should_not_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 69)); -// assert_noop!( -// Balances::transfer(Some(1).into(), 2, 69), -// Error::<$test, _>::InsufficientBalance, -// ); -// }); -// } - -// #[test] -// fn deducting_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 69)); -// assert_eq!(Balances::free_balance(1), 42); -// }); -// } - -// #[test] -// fn refunding_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 42); -// assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); -// Balances::unreserve(&1, 69); -// assert_eq!(Balances::free_balance(1), 111); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn slashing_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 69)); -// assert!(Balances::slash(&1, 69).1.is_zero()); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 42); -// assert_eq!(>::get(), 42); -// }); -// } - -// #[test] -// fn withdrawing_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&2, 111); -// let _ = Balances::withdraw( -// &2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive -// ); -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Withdraw { who: 2, amount: 11 })); -// assert_eq!(Balances::free_balance(2), 100); -// assert_eq!(>::get(), 100); -// }); -// } - -// #[test] -// fn slashing_incomplete_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 42); -// assert_ok!(Balances::reserve(&1, 21)); -// assert_eq!(Balances::slash(&1, 69).1, 27); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(>::get(), 0); -// }); -// } - -// #[test] -// fn unreserving_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 111)); -// Balances::unreserve(&1, 42); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 42); -// }); -// } - -// #[test] -// fn slashing_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 111)); -// assert_eq!(Balances::slash_reserved(&1, 42).1, 0); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(>::get(), 69); -// }); -// } - -// #[test] -// fn slashing_incomplete_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 42)); -// assert_eq!(Balances::slash_reserved(&1, 69).1, 27); -// assert_eq!(Balances::free_balance(1), 69); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(>::get(), 69); -// }); -// } - -// #[test] -// fn repatriating_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 1); -// assert_ok!(Balances::reserve(&1, 110)); -// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); -// System::assert_last_event( -// RuntimeEvent::Balances(crate::Event::ReserveRepatriated { from: 1, to: 2, amount: 41, destination_status: Status::Free }) -// ); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::free_balance(2), 42); -// }); -// } - -// #[test] -// fn transferring_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 1); -// assert_ok!(Balances::reserve(&1, 110)); -// assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); -// assert_eq!(Balances::reserved_balance(1), 69); -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(2), 41); -// assert_eq!(Balances::free_balance(2), 1); -// }); -// } - -// #[test] -// fn transferring_reserved_balance_to_yourself_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// assert_ok!(Balances::reserve(&1, 50)); -// assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Status::Free), 0); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance(1), 0); - -// assert_ok!(Balances::reserve(&1, 50)); -// assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Status::Free), 10); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn transferring_reserved_balance_to_nonexistent_should_fail() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(Balances::reserve(&1, 111)); -// assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); -// }); -// } - -// #[test] -// fn transferring_incomplete_reserved_balance_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 1); -// assert_ok!(Balances::reserve(&1, 41)); -// assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Status::Free), 28); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::free_balance(1), 69); -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::free_balance(2), 42); -// }); -// } - -// #[test] -// fn transferring_too_high_value_should_not_panic() { -// <$ext_builder>::default().build().execute_with(|| { -// Balances::make_free_balance_be(&1, u64::MAX); -// Balances::make_free_balance_be(&2, 1); - -// assert_err!( -// Balances::transfer(Some(1).into(), 2, u64::MAX), -// ArithmeticError::Overflow, -// ); - -// assert_eq!(Balances::free_balance(1), u64::MAX); -// assert_eq!(Balances::free_balance(2), 1); -// }); -// } - -// #[test] -// fn account_create_on_free_too_low_with_other() { -// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 100); -// assert_eq!(>::get(), 100); - -// // No-op. -// let _ = Balances::deposit_creating(&2, 50); -// assert_eq!(Balances::free_balance(2), 0); -// assert_eq!(>::get(), 100); -// }) -// } - -// #[test] -// fn account_create_on_free_too_low() { -// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { -// // No-op. -// let _ = Balances::deposit_creating(&2, 50); -// assert_eq!(Balances::free_balance(2), 0); -// assert_eq!(>::get(), 0); -// }) -// } - -// #[test] -// fn account_removal_on_free_too_low() { -// <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { -// assert_eq!(>::get(), 0); - -// // Setup two accounts with free balance above the existential threshold. -// let _ = Balances::deposit_creating(&1, 110); -// let _ = Balances::deposit_creating(&2, 110); - -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::free_balance(2), 110); -// assert_eq!(>::get(), 220); - -// // Transfer funds from account 1 of such amount that after this transfer -// // the balance of account 1 will be below the existential threshold. -// // This should lead to the removal of all balance of this account. -// assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); - -// // Verify free balance removal of account 1. -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::free_balance(2), 130); - -// // Verify that TotalIssuance tracks balance removal when free balance is too low. -// assert_eq!(>::get(), 130); -// }); -// } - -// #[test] -// fn burn_must_work() { -// <$ext_builder>::default().monied(true).build().execute_with(|| { -// let init_total_issuance = Balances::total_issuance(); -// let imbalance = Balances::burn(10); -// assert_eq!(Balances::total_issuance(), init_total_issuance - 10); -// drop(imbalance); -// assert_eq!(Balances::total_issuance(), init_total_issuance); -// }); -// } - -// #[test] -// fn transfer_keep_alive_works() { -// <$ext_builder>::default().existential_deposit(1).build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 100); -// assert_noop!( -// Balances::transfer_keep_alive(Some(1).into(), 2, 100), -// Error::<$test, _>::KeepAlive -// ); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 0); -// }); -// } - -// #[test] -// #[should_panic = "the balance of any account should always be at least the existential deposit."] -// fn cannot_set_genesis_value_below_ed() { -// ($existential_deposit).with(|v| *v.borrow_mut() = 11); -// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); -// let _ = pallet_balances::GenesisConfig::<$test> { -// balances: vec![(1, 10)], -// }.assimilate_storage(&mut t).unwrap(); -// } - -// #[test] -// #[should_panic = "duplicate balances in genesis."] -// fn cannot_set_genesis_value_twice() { -// let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); -// let _ = pallet_balances::GenesisConfig::<$test> { -// balances: vec![(1, 10), (2, 20), (1, 15)], -// }.assimilate_storage(&mut t).unwrap(); -// } - -// #[test] -// fn dust_moves_between_free_and_reserved() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// // Set balance to free and reserved at the existential deposit -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); -// // Check balance -// assert_eq!(Balances::free_balance(1), 100); -// assert_eq!(Balances::reserved_balance(1), 0); - -// // Reserve some free balance -// assert_ok!(Balances::reserve(&1, 50)); -// // Check balance, the account should be ok. -// assert_eq!(Balances::free_balance(1), 50); -// assert_eq!(Balances::reserved_balance(1), 50); - -// // Reserve the rest of the free balance -// assert_ok!(Balances::reserve(&1, 50)); -// // Check balance, the account should be ok. -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 100); - -// // Unreserve everything -// Balances::unreserve(&1, 100); -// // Check balance, all 100 should move to free_balance -// assert_eq!(Balances::free_balance(1), 100); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn account_deleted_when_just_dust() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// // Set balance to free and reserved at the existential deposit -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 50, 50)); -// // Check balance -// assert_eq!(Balances::free_balance(1), 50); -// assert_eq!(Balances::reserved_balance(1), 50); - -// // Reserve some free balance -// let res = Balances::slash(&1, 1); -// assert_eq!(res, (NegativeImbalance::new(1), 0)); - -// // The account should be dead. -// assert_eq!(Balances::free_balance(1), 0); -// assert_eq!(Balances::reserved_balance(1), 0); -// }); -// } - -// #[test] -// fn emit_events_with_reserve_and_unreserve() { -// <$ext_builder>::default() -// .build() -// .execute_with(|| { -// let _ = Balances::deposit_creating(&1, 100); - -// System::set_block_number(2); -// assert_ok!(Balances::reserve(&1, 10)); - -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { who: 1, amount: 10 })); - -// System::set_block_number(3); -// assert!(Balances::unreserve(&1, 5).is_zero()); - -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); - -// System::set_block_number(4); -// assert_eq!(Balances::unreserve(&1, 6), 1); - -// // should only unreserve 5 -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { who: 1, amount: 5 })); -// }); -// } - -// #[test] -// fn emit_events_with_existential_deposit() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), -// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), -// ] -// ); - -// let res = Balances::slash(&1, 1); -// assert_eq!(res, (NegativeImbalance::new(1), 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), -// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), -// ] -// ); -// }); -// } - -// #[test] -// fn emit_events_with_no_existential_deposit_suicide() { -// <$ext_builder>::default() -// .existential_deposit(1) -// .build() -// .execute_with(|| { -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), -// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), -// ] -// ); - -// let res = Balances::slash(&1, 100); -// assert_eq!(res, (NegativeImbalance::new(100), 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), -// ] -// ); -// }); -// } - -// #[test] -// fn slash_loop_works() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// /* User has no reference counter, so they can die in these scenarios */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 900 })); - -// // SCENARIO: Slash will kill account because not enough balance left. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); -// // Account is killed -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash will kill account, and report missing slash amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed full free_balance, and reports 300 not slashed -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); -// // Account is dead -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, but keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, and kill. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); -// // Account is dead because 50 reserved balance is not enough to keep alive -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash can take as much as possible from reserved, kill, and report missing amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); -// // Account is super dead -// assert!(!System::account_exists(&1)); - -// /* User will now have a reference counter on them, keeping them alive in these scenarios */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Slash will take as much as possible without killing account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed completed in full -// assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(900), 50)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash will not kill account, and report missing slash amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 0)); -// // Slashed full free_balance minus ED, and reports 400 not slashed -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(900), 400)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, but keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 400)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1300), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take from reserved, but keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 350)); -// // Slashed full free_balance and 250 of reserved balance to leave ED -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1250), 50)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash can take as much as possible from reserved and report missing amount. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 1_000, 250)); -// // Slashed full free_balance and 300 of reserved balance -// assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1150), 150)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // Slash on non-existent account is okay. -// assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); -// }); -// } - -// #[test] -// fn slash_reserved_loop_works() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// /* User has no reference counter, so they can die in these scenarios */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Slash would kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(1_000), 0)); -// // Account is dead -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash would kill account, and reports left over slash. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); -// // Account is dead -// assert!(!System::account_exists(&1)); - -// // SCENARIO: Over-slash does not take from free balance. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 300, 1_000)); -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); -// // Account is alive because of free balance -// assert!(System::account_exists(&1)); - -// /* User has a reference counter, so they cannot die */ -// // SCENARIO: Slash would not kill account. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests -// // Slashed completed in full -// assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Slash as much as possible without killing. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed as much as possible -// assert_eq!(Balances::slash_reserved(&1, 1_000), (NegativeImbalance::new(950), 50)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash reports correctly, where reserved is needed to keep alive. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 50, 1_000)); -// // Slashed as much as possible -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(950), 350)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // SCENARIO: Over-slash reports correctly, where full reserved is removed. -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 1_000)); -// // Slashed as much as possible -// assert_eq!(Balances::slash_reserved(&1, 1_300), (NegativeImbalance::new(1_000), 300)); -// // Account is still alive -// assert!(System::account_exists(&1)); - -// // Slash on non-existent account is okay. -// assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); -// }); -// } - -// #[test] -// fn operations_on_dead_account_should_not_change_state() { -// // These functions all use `mutate_account` which may introduce a storage change when -// // the account never existed to begin with, and shouldn't exist in the end. -// <$ext_builder>::default() -// .existential_deposit(0) -// .build() -// .execute_with(|| { -// assert!(!frame_system::Account::::contains_key(&1337)); - -// // Unreserve -// assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); -// // Reserve -// assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); -// // Slash Reserve -// assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); -// // Repatriate Reserve -// assert_noop!(Balances::repatriate_reserved(&1337, &1338, 42, Status::Free), Error::::DeadAccount); -// // Slash -// assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); -// }); -// } - -// #[test] -// fn transfer_keep_alive_all_free_succeed() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 100, 100)); -// assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 100); -// }); -// } - -// #[test] -// fn transfer_all_works() { -// <$ext_builder>::default() -// .existential_deposit(100) -// .build() -// .execute_with(|| { -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and allow death -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); -// assert_eq!(Balances::total_balance(&1), 0); -// assert_eq!(Balances::total_balance(&2), 200); - -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 0)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and keep alive -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 100); - -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and allow death w/ reserved -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); -// assert_eq!(Balances::total_balance(&1), 0); -// assert_eq!(Balances::total_balance(&2), 200); - -// // setup -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1, 200, 10)); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 2, 0, 0)); -// // transfer all and keep alive w/ reserved -// assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); -// assert_eq!(Balances::total_balance(&1), 100); -// assert_eq!(Balances::total_balance(&2), 110); -// }); -// } - -// #[test] -// fn named_reserve_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// let id_1 = [1u8; 8]; -// let id_2 = [2u8; 8]; -// let id_3 = [3u8; 8]; - -// // reserve - -// assert_noop!(Balances::reserve_named(&id_1, &1, 112), Error::::InsufficientBalance); - -// assert_ok!(Balances::reserve_named(&id_1, &1, 12)); - -// assert_eq!(Balances::reserved_balance(1), 12); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - -// assert_ok!(Balances::reserve_named(&id_1, &1, 2)); - -// assert_eq!(Balances::reserved_balance(1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - -// assert_ok!(Balances::reserve_named(&id_2, &1, 23)); - -// assert_eq!(Balances::reserved_balance(1), 37); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - -// assert_ok!(Balances::reserve(&1, 34)); - -// assert_eq!(Balances::reserved_balance(1), 71); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 40); - -// assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); - -// // unreserve - -// assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); - -// assert_eq!(Balances::reserved_balance(1), 61); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - -// assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); - -// assert_eq!(Balances::reserved_balance(1), 57); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - -// assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); - -// assert_eq!(Balances::reserved_balance(1), 54); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); - -// assert_eq!(Balances::total_balance(&1), 111); -// assert_eq!(Balances::free_balance(1), 57); - -// // slash_reserved_named - -// assert_ok!(Balances::reserve_named(&id_1, &1, 10)); - -// assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); - -// assert_eq!(Balances::reserved_balance(1), 54); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); -// assert_eq!(Balances::total_balance(&1), 101); - -// assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); - -// assert_eq!(Balances::reserved_balance(1), 49); -// assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); -// assert_eq!(Balances::total_balance(&1), 96); - -// // repatriate_reserved_named - -// let _ = Balances::deposit_creating(&2, 100); - -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Reserved).unwrap(), 0); - -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); -// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); -// assert_eq!(Balances::reserved_balance(&2), 10); - -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Status::Reserved).unwrap(), 1); - -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); -// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); -// assert_eq!(Balances::reserved_balance(&2), 0); - -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Status::Free).unwrap(), 0); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); -// assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); -// assert_eq!(Balances::free_balance(&2), 110); - -// // repatriate_reserved_named to self - -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Status::Reserved).unwrap(), 5); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); - -// assert_eq!(Balances::free_balance(&1), 47); - -// assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Status::Free).unwrap(), 10); -// assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - -// assert_eq!(Balances::free_balance(&1), 52); -// }); -// } - -// #[test] -// fn reserved_named_to_yourself_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 110); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::reserve_named(&id, &1, 50)); -// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Status::Free), 0); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); - -// assert_ok!(Balances::reserve_named(&id, &1, 50)); -// assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Status::Free), 10); -// assert_eq!(Balances::free_balance(1), 110); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// }); -// } - -// #[test] -// fn ensure_reserved_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 15); - -// assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 10); - -// assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 20); -// }); -// } - -// #[test] -// fn unreserve_all_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::reserve_named(&id, &1, 15)); - -// assert_eq!(Balances::unreserve_all_named(&id, &1), 15); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_eq!(Balances::free_balance(&1), 111); - -// assert_eq!(Balances::unreserve_all_named(&id, &1), 0); -// }); -// } - -// #[test] -// fn slash_all_reserved_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::reserve_named(&id, &1, 15)); - -// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_eq!(Balances::free_balance(&1), 96); - -// assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); -// }); -// } - -// #[test] -// fn repatriate_all_reserved_named_should_work() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// let _ = Balances::deposit_creating(&2, 10); -// let _ = Balances::deposit_creating(&3, 10); - -// let id = [1u8; 8]; - -// assert_ok!(Balances::reserve_named(&id, &1, 15)); - -// assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Status::Reserved)); -// assert_eq!(Balances::reserved_balance_named(&id, &1), 0); -// assert_eq!(Balances::reserved_balance_named(&id, &2), 15); - -// assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Status::Free)); -// assert_eq!(Balances::reserved_balance_named(&id, &2), 0); -// assert_eq!(Balances::free_balance(&3), 25); -// }); -// } - -// #[test] -// fn set_balance_handles_killing_account() { -// <$ext_builder>::default().build().execute_with(|| { -// let _ = Balances::deposit_creating(&1, 111); -// assert_ok!(frame_system::Pallet::::inc_consumers(&1)); -// assert_noop!( -// Balances::set_balance(RuntimeOrigin::root(), 1, 0, 0), -// DispatchError::ConsumerRemaining, -// ); -// }); -// } - -// #[test] -// fn set_balance_handles_total_issuance() { -// <$ext_builder>::default().build().execute_with(|| { -// let old_total_issuance = Balances::total_issuance(); -// assert_ok!(Balances::set_balance(RuntimeOrigin::root(), 1337, 69, 42)); -// assert_eq!(Balances::total_issuance(), old_total_issuance + 69 + 42); -// assert_eq!(Balances::total_balance(&1337), 69 + 42); -// assert_eq!(Balances::free_balance(&1337), 69); -// assert_eq!(Balances::reserved_balance(&1337), 42); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_set_balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_eq!(>::balance(&1337), 0); -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!(>::balance(&1337), 100); - -// assert_ok!(Balances::reserve(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); - -// assert_noop!(>::set_balance(&1337, 0), ArithmeticError::Underflow); - -// assert_ok!(>::set_balance(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 0); -// assert_eq!(Balances::reserved_balance(1337), 60); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_set_total_issuance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_eq!(>::total_issuance(), 0); -// >::set_total_issuance(100); -// assert_eq!(>::total_issuance(), 100); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_decrease_balance_simple_works() { -// <$ext_builder>::default().build().execute_with(|| { -// // An Account that starts at 100 -// assert_ok!(>::set_balance(&1337, 100)); -// // and reserves 50 -// assert_ok!(Balances::reserve(&1337, 50)); -// // and is decreased by 20 -// assert_ok!(>::decrease_balance(&1337, 20)); -// // should end up at 80. -// assert_eq!(>::balance(&1337), 80); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_decrease_balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!(>::balance(&1337), 100); - -// assert_noop!( -// >::decrease_balance(&1337, 101), -// TokenError::NoFunds -// ); -// assert_eq!( -// >::decrease_balance(&1337, 100), -// Ok(100) -// ); -// assert_eq!(>::balance(&1337), 0); - -// // free: 40, reserved: 60 -// assert_ok!(>::set_balance(&1337, 100)); -// assert_ok!(Balances::reserve(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); -// assert_noop!( -// >::decrease_balance(&1337, 41), -// TokenError::NoFunds -// ); -// assert_eq!( -// >::decrease_balance(&1337, 40), -// Ok(40) -// ); -// assert_eq!(>::balance(&1337), 60); -// assert_eq!(Balances::free_balance(1337), 0); -// assert_eq!(Balances::reserved_balance(1337), 60); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_decrease_balance_at_most_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!(>::balance(&1337), 100); - -// assert_eq!( -// >::decrease_balance_at_most(&1337, 101), -// 100 -// ); -// assert_eq!(>::balance(&1337), 0); - -// assert_ok!(>::set_balance(&1337, 100)); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 100), -// 100 -// ); -// assert_eq!(>::balance(&1337), 0); - -// // free: 40, reserved: 60 -// assert_ok!(>::set_balance(&1337, 100)); -// assert_ok!(Balances::reserve(&1337, 60)); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 0), -// 0 -// ); -// assert_eq!(Balances::free_balance(1337) , 40); -// assert_eq!(Balances::reserved_balance(1337), 60); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 10), -// 10 -// ); -// assert_eq!(Balances::free_balance(1337), 30); -// assert_eq!( -// >::decrease_balance_at_most(&1337, 200), -// 30 -// ); -// assert_eq!(>::balance(&1337), 60); -// assert_eq!(Balances::free_balance(1337), 0); -// assert_eq!(Balances::reserved_balance(1337), 60); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_increase_balance_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_noop!( -// >::increase_balance(&1337, 0), -// TokenError::BelowMinimum -// ); -// assert_eq!( -// >::increase_balance(&1337, 1), -// Ok(1) -// ); -// assert_noop!( -// >::increase_balance(&1337, u64::MAX), -// ArithmeticError::Overflow -// ); -// }); -// } - -// #[test] -// fn fungible_unbalanced_trait_increase_balance_at_most_works() { -// <$ext_builder>::default().build().execute_with(|| { -// assert_eq!( -// >::increase_balance_at_most(&1337, 0), -// 0 -// ); -// assert_eq!( -// >::increase_balance_at_most(&1337, 1), -// 1 -// ); -// assert_eq!( -// >::increase_balance_at_most(&1337, u64::MAX), -// u64::MAX - 1 -// ); -// }); -// } -// } -// } diff --git a/pallets/native-barrier/src/tests_composite.rs b/pallets/native-barrier/src/tests_composite.rs deleted file mode 100644 index 07e3232fb..000000000 --- a/pallets/native-barrier/src/tests_composite.rs +++ /dev/null @@ -1,149 +0,0 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2018-2022 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 - -// #![cfg(test)] - -// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; -// use frame_support::{ -// dispatch::DispatchInfo, -// parameter_types, -// traits::{ConstU32, ConstU64, ConstU8}, -// weights::{IdentityFee, Weight}, -// }; -// use pallet_transaction_payment::CurrencyAdapter; -// use sp_core::H256; -// use sp_io; -// use sp_runtime::{testing::Header, traits::IdentityLookup}; -// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -// type Block = frame_system::mocking::MockBlock; - -// frame_support::construct_runtime!( -// pub enum Test where -// Block = Block, -// NodeBlock = Block, -// UncheckedExtrinsic = UncheckedExtrinsic, -// { -// System: frame_system::{Pallet, Call, Config, Storage, Event}, -// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, -// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, -// } -// ); - -// parameter_types! { -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max( -// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), -// ); -// pub static ExistentialDeposit: u64 = 0; -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = frame_support::traits::Everything; -// type BlockWeights = BlockWeights; -// type BlockLength = (); -// type DbWeight = (); -// type RuntimeOrigin = RuntimeOrigin; -// type Index = u64; -// type BlockNumber = u64; -// type RuntimeCall = RuntimeCall; -// type Hash = H256; -// type Hashing = ::sp_runtime::traits::BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type RuntimeEvent = RuntimeEvent; -// type BlockHashCount = ConstU64<250>; -// type Version = (); -// type PalletInfo = PalletInfo; -// type AccountData = super::AccountData; -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// type SS58Prefix = (); -// type OnSetCode = (); -// type MaxConsumers = frame_support::traits::ConstU32<16>; -// } - -// impl pallet_transaction_payment::Config for Test { -// type RuntimeEvent = RuntimeEvent; -// type OnChargeTransaction = CurrencyAdapter, ()>; -// type OperationalFeeMultiplier = ConstU8<5>; -// type WeightToFee = IdentityFee; -// type LengthToFee = IdentityFee; -// type FeeMultiplierUpdate = (); -// } - -// impl Config for Test { -// type Balance = u64; -// type DustRemoval = (); -// type RuntimeEvent = RuntimeEvent; -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = frame_system::Pallet; -// type MaxLocks = (); -// type MaxReserves = ConstU32<2>; -// type ReserveIdentifier = [u8; 8]; -// type WeightInfo = (); -// } - -// pub struct ExtBuilder { -// existential_deposit: u64, -// monied: bool, -// } -// impl Default for ExtBuilder { -// fn default() -> Self { -// Self { existential_deposit: 1, monied: false } -// } -// } -// impl ExtBuilder { -// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { -// self.existential_deposit = existential_deposit; -// self -// } -// pub fn monied(mut self, monied: bool) -> Self { -// self.monied = monied; -// self -// } -// pub fn set_associated_consts(&self) { -// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); -// } -// pub fn build(self) -> sp_io::TestExternalities { -// self.set_associated_consts(); -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { -// balances: if self.monied { -// vec![ -// (1, 10 * self.existential_deposit), -// (2, 20 * self.existential_deposit), -// (3, 30 * self.existential_deposit), -// (4, 40 * self.existential_deposit), -// (12, 10 * self.existential_deposit), -// ] -// } else { -// vec![] -// }, -// } -// .assimilate_storage(&mut t) -// .unwrap(); - -// let mut ext = sp_io::TestExternalities::new(t); -// ext.execute_with(|| System::set_block_number(1)); -// ext -// } -// } - -// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } diff --git a/pallets/native-barrier/src/tests_local.rs b/pallets/native-barrier/src/tests_local.rs deleted file mode 100644 index 4f2cd2483..000000000 --- a/pallets/native-barrier/src/tests_local.rs +++ /dev/null @@ -1,191 +0,0 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2018-2022 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 - -// #![cfg(test)] - -// use crate::{self as pallet_balances, decl_tests, Config, Pallet}; -// use frame_support::{ -// dispatch::DispatchInfo, -// parameter_types, -// traits::{ConstU32, ConstU64, ConstU8, StorageMapShim}, -// weights::{IdentityFee, Weight}, -// }; -// use pallet_transaction_payment::CurrencyAdapter; -// use sp_core::H256; -// use sp_io; -// use sp_runtime::{testing::Header, traits::IdentityLookup}; - -// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -// type Block = frame_system::mocking::MockBlock; - -// frame_support::construct_runtime!( -// pub struct Test where -// Block = Block, -// NodeBlock = Block, -// UncheckedExtrinsic = UncheckedExtrinsic, -// { -// System: frame_system::{Pallet, Call, Config, Storage, Event}, -// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, -// TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, -// } -// ); - -// parameter_types! { -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max( -// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), -// ); -// pub static ExistentialDeposit: u64 = 0; -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = frame_support::traits::Everything; -// type BlockWeights = BlockWeights; -// type BlockLength = (); -// type DbWeight = (); -// type RuntimeOrigin = RuntimeOrigin; -// type Index = u64; -// type BlockNumber = u64; -// type RuntimeCall = RuntimeCall; -// type Hash = H256; -// type Hashing = ::sp_runtime::traits::BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type RuntimeEvent = RuntimeEvent; -// type BlockHashCount = ConstU64<250>; -// type Version = (); -// type PalletInfo = PalletInfo; -// type AccountData = (); -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// type SS58Prefix = (); -// type OnSetCode = (); -// type MaxConsumers = frame_support::traits::ConstU32<16>; -// } - -// impl pallet_transaction_payment::Config for Test { -// type RuntimeEvent = RuntimeEvent; -// type OnChargeTransaction = CurrencyAdapter, ()>; -// type OperationalFeeMultiplier = ConstU8<5>; -// type WeightToFee = IdentityFee; -// type LengthToFee = IdentityFee; -// type FeeMultiplierUpdate = (); -// } - -// impl Config for Test { -// type Balance = u64; -// type DustRemoval = (); -// type RuntimeEvent = RuntimeEvent; -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = -// StorageMapShim, system::Provider, u64, super::AccountData>; -// type MaxLocks = ConstU32<50>; -// type MaxReserves = ConstU32<2>; -// type ReserveIdentifier = [u8; 8]; -// type WeightInfo = (); -// } - -// pub struct ExtBuilder { -// existential_deposit: u64, -// monied: bool, -// } -// impl Default for ExtBuilder { -// fn default() -> Self { -// Self { existential_deposit: 1, monied: false } -// } -// } -// impl ExtBuilder { -// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { -// self.existential_deposit = existential_deposit; -// self -// } -// pub fn monied(mut self, monied: bool) -> Self { -// self.monied = monied; -// if self.existential_deposit == 0 { -// self.existential_deposit = 1; -// } -// self -// } -// pub fn set_associated_consts(&self) { -// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); -// } -// pub fn build(self) -> sp_io::TestExternalities { -// self.set_associated_consts(); -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { -// balances: if self.monied { -// vec![ -// (1, 10 * self.existential_deposit), -// (2, 20 * self.existential_deposit), -// (3, 30 * self.existential_deposit), -// (4, 40 * self.existential_deposit), -// (12, 10 * self.existential_deposit), -// ] -// } else { -// vec![] -// }, -// } -// .assimilate_storage(&mut t) -// .unwrap(); - -// let mut ext = sp_io::TestExternalities::new(t); -// ext.execute_with(|| System::set_block_number(1)); -// ext -// } -// } - -// decl_tests! { Test, ExtBuilder, EXISTENTIAL_DEPOSIT } - -// #[test] -// fn emit_events_with_no_existential_deposit_suicide_with_dust() { -// ::default().existential_deposit(2).build().execute_with(|| { -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::NewAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), -// RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100, reserved: 0 }), -// ] -// ); - -// let res = Balances::slash(&1, 98); -// assert_eq!(res, (NegativeImbalance::new(98), 0)); - -// // no events -// assert_eq!( -// events(), -// [RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 98 })] -// ); - -// let res = Balances::slash(&1, 1); -// assert_eq!(res, (NegativeImbalance::new(1), 0)); - -// assert_eq!( -// events(), -// [ -// RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), -// RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 1 }), -// RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }) -// ] -// ); -// }); -// } diff --git a/pallets/native-barrier/src/tests_reentrancy.rs b/pallets/native-barrier/src/tests_reentrancy.rs deleted file mode 100644 index 61814e598..000000000 --- a/pallets/native-barrier/src/tests_reentrancy.rs +++ /dev/null @@ -1,264 +0,0 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2018-2022 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 setup for potential reentracy and lost updates of nested mutations. - -// #![cfg(test)] - -// use crate::{self as pallet_balances, Config}; -// use frame_support::{ -// parameter_types, -// traits::{ConstU32, ConstU64, StorageMapShim}, -// }; -// use sp_core::H256; -// use sp_io; -// use sp_runtime::{testing::Header, traits::IdentityLookup}; - -// use crate::*; -// use frame_support::{ -// assert_ok, -// traits::{Currency, ReservableCurrency}, -// }; -// use frame_system::RawOrigin; - -// type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -// type Block = frame_system::mocking::MockBlock; - -// frame_support::construct_runtime!( -// pub enum Test where -// Block = Block, -// NodeBlock = Block, -// UncheckedExtrinsic = UncheckedExtrinsic, -// { -// System: frame_system::{Pallet, Call, Config, Storage, Event}, -// Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, -// } -// ); - -// parameter_types! { -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max( -// frame_support::weights::Weight::from_ref_time(1024).set_proof_size(u64::MAX), -// ); -// pub static ExistentialDeposit: u64 = 0; -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = frame_support::traits::Everything; -// type BlockWeights = BlockWeights; -// type BlockLength = (); -// type DbWeight = (); -// type RuntimeOrigin = RuntimeOrigin; -// type Index = u64; -// type BlockNumber = u64; -// type RuntimeCall = RuntimeCall; -// type Hash = H256; -// type Hashing = ::sp_runtime::traits::BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type RuntimeEvent = RuntimeEvent; -// type BlockHashCount = ConstU64<250>; -// type Version = (); -// type PalletInfo = PalletInfo; -// type AccountData = (); -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// type SS58Prefix = (); -// type OnSetCode = (); -// type MaxConsumers = frame_support::traits::ConstU32<16>; -// } - -// pub struct OnDustRemoval; -// impl OnUnbalanced> for OnDustRemoval { -// fn on_nonzero_unbalanced(amount: NegativeImbalance) { -// assert_ok!(Balances::resolve_into_existing(&1, amount)); -// } -// } - -// impl Config for Test { -// type Balance = u64; -// type DustRemoval = OnDustRemoval; -// type RuntimeEvent = RuntimeEvent; -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = -// StorageMapShim, system::Provider, u64, super::AccountData>; -// type MaxLocks = ConstU32<50>; -// type MaxReserves = ConstU32<2>; -// type ReserveIdentifier = [u8; 8]; -// type WeightInfo = (); -// } - -// pub struct ExtBuilder { -// existential_deposit: u64, -// } -// impl Default for ExtBuilder { -// fn default() -> Self { -// Self { existential_deposit: 1 } -// } -// } -// impl ExtBuilder { -// pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { -// self.existential_deposit = existential_deposit; -// self -// } - -// pub fn set_associated_consts(&self) { -// EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); -// } - -// pub fn build(self) -> sp_io::TestExternalities { -// self.set_associated_consts(); -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { balances: vec![] } -// .assimilate_storage(&mut t) -// .unwrap(); -// let mut ext = sp_io::TestExternalities::new(t); -// ext.execute_with(|| System::set_block_number(1)); -// ext -// } -// } - -// #[test] -// fn transfer_dust_removal_tst1_should_work() { -// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { -// // Verification of reentrancy in dust removal -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - -// // In this transaction, account 2 free balance -// // drops below existential balance -// // and dust balance is removed from account 2 -// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 3, 450)); - -// // As expected dust balance is removed. -// assert_eq!(Balances::free_balance(&2), 0); - -// // As expected beneficiary account 3 -// // received the transfered fund. -// assert_eq!(Balances::free_balance(&3), 450); - -// // Dust balance is deposited to account 1 -// // during the process of dust removal. -// assert_eq!(Balances::free_balance(&1), 1050); - -// // Verify the events -// assert_eq!(System::events().len(), 12); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { -// from: 2, -// to: 3, -// amount: 450, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { -// account: 2, -// amount: 50, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { -// who: 1, -// amount: 50, -// })); -// }); -// } - -// #[test] -// fn transfer_dust_removal_tst2_should_work() { -// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { -// // Verification of reentrancy in dust removal -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - -// // In this transaction, account 2 free balance -// // drops below existential balance -// // and dust balance is removed from account 2 -// assert_ok!(Balances::transfer(RawOrigin::Signed(2).into(), 1, 450)); - -// // As expected dust balance is removed. -// assert_eq!(Balances::free_balance(&2), 0); - -// // Dust balance is deposited to account 1 -// // during the process of dust removal. -// assert_eq!(Balances::free_balance(&1), 1500); - -// // Verify the events -// assert_eq!(System::events().len(), 10); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { -// from: 2, -// to: 1, -// amount: 450, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { -// account: 2, -// amount: 50, -// })); -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { -// who: 1, -// amount: 50, -// })); -// }); -// } - -// #[test] -// fn repatriating_reserved_balance_dust_removal_should_work() { -// ExtBuilder::default().existential_deposit(100).build().execute_with(|| { -// // Verification of reentrancy in dust removal -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); -// assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - -// // Reserve a value on account 2, -// // Such that free balance is lower than -// // Exestintial deposit. -// assert_ok!(Balances::reserve(&2, 450)); - -// // Transfer of reserved fund from slashed account 2 to -// // beneficiary account 1 -// assert_ok!(Balances::repatriate_reserved(&2, &1, 450, Status::Free), 0); - -// // Since free balance of account 2 is lower than -// // existential deposit, dust amount is -// // removed from the account 2 -// assert_eq!(Balances::reserved_balance(2), 0); -// assert_eq!(Balances::free_balance(2), 0); - -// // account 1 is credited with reserved amount -// // together with dust balance during dust -// // removal. -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::free_balance(1), 1500); - -// // Verify the events -// assert_eq!(System::events().len(), 11); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { -// from: 2, -// to: 1, -// amount: 450, -// destination_status: Status::Free, -// })); - -// System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { -// account: 2, -// amount: 50, -// })); - -// System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { -// who: 1, -// amount: 50, -// })); -// }); -// } diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index 6324745fd..432b89c76 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -47,118 +47,79 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_balances. pub trait WeightInfo { - fn transfer() -> Weight; - fn transfer_keep_alive() -> Weight; - fn set_balance_creating() -> Weight; - fn set_balance_killing() -> Weight; - fn force_transfer() -> Weight; - fn transfer_all() -> Weight; - fn force_unreserve() -> Weight; + + fn set_start_unix_time() -> Weight; + + fn set_daily_xcm_limit() -> Weight; + + fn add_accounts_to_native_barrier() -> Weight; + + fn remove_accounts_to_native_barrier() -> Weight; } /// Weights for pallet_balances using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { // Storage: System Account (r:1 w:1) - fn transfer() -> Weight { + fn set_start_unix_time() -> Weight { // Minimum execution time: 48_134 nanoseconds. Weight::from_ref_time(48_811_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn transfer_keep_alive() -> Weight { + fn set_daily_xcm_limit() -> Weight { // Minimum execution time: 36_586 nanoseconds. Weight::from_ref_time(36_966_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn set_balance_creating() -> Weight { + fn add_accounts_to_native_barrier() -> Weight { // Minimum execution time: 28_486 nanoseconds. Weight::from_ref_time(28_940_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn set_balance_killing() -> Weight { + fn remove_accounts_to_native_barrier() -> Weight { // Minimum execution time: 31_225 nanoseconds. Weight::from_ref_time(31_946_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } - // Storage: System Account (r:2 w:2) - fn force_transfer() -> Weight { - // Minimum execution time: 47_347 nanoseconds. - Weight::from_ref_time(48_005_000 as u64) - .saturating_add(T::DbWeight::get().reads(2 as u64)) - .saturating_add(T::DbWeight::get().writes(2 as u64)) - } - // Storage: System Account (r:1 w:1) - fn transfer_all() -> Weight { - // Minimum execution time: 41_668 nanoseconds. - Weight::from_ref_time(42_232_000 as u64) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) - } - // Storage: System Account (r:1 w:1) - fn force_unreserve() -> Weight { - // Minimum execution time: 23_741 nanoseconds. - Weight::from_ref_time(24_073_000 as u64) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) - } + } // For backwards compatibility and tests impl WeightInfo for () { // Storage: System Account (r:1 w:1) - fn transfer() -> Weight { + fn set_start_unix_time() -> Weight { // Minimum execution time: 48_134 nanoseconds. Weight::from_ref_time(48_811_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn transfer_keep_alive() -> Weight { + fn set_daily_xcm_limit() -> Weight { // Minimum execution time: 36_586 nanoseconds. Weight::from_ref_time(36_966_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn set_balance_creating() -> Weight { + fn add_accounts_to_native_barrier() -> Weight { // Minimum execution time: 28_486 nanoseconds. Weight::from_ref_time(28_940_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn set_balance_killing() -> Weight { + fn remove_accounts_to_native_barrier() -> Weight { // Minimum execution time: 31_225 nanoseconds. Weight::from_ref_time(31_946_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } - // Storage: System Account (r:2 w:2) - fn force_transfer() -> Weight { - // Minimum execution time: 47_347 nanoseconds. - Weight::from_ref_time(48_005_000 as u64) - .saturating_add(RocksDbWeight::get().reads(2 as u64)) - .saturating_add(RocksDbWeight::get().writes(2 as u64)) - } - // Storage: System Account (r:1 w:1) - fn transfer_all() -> Weight { - // Minimum execution time: 41_668 nanoseconds. - Weight::from_ref_time(42_232_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) - } - // Storage: System Account (r:1 w:1) - fn force_unreserve() -> Weight { - // Minimum execution time: 23_741 nanoseconds. - Weight::from_ref_time(24_073_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) - } + } From 117c7d7299eda601be8b0cd6e91c9c12dd69e842 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 15 Aug 2023 12:35:18 +0300 Subject: [PATCH 15/69] add events Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 0bfd91e81..9eef7dca2 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -80,10 +80,11 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::set_start_unix_time())] pub fn set_start_unix_time( origin: OriginFor, - start_unix_time: Option, + start_unix_time: core::time::Duration, ) -> DispatchResult { ensure_root(origin)?; - >::set(start_unix_time); + >::set(Some(start_unix_time)); + Self::deposit_event(Event::StartUnixTime { start_unix_time }); Ok(()) } @@ -96,6 +97,9 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; >::set(Some(daily_xcm_limit)); + Self::deposit_event(Event::DailyLimitSet { + daily_limit: daily_xcm_limit, + }); Ok(()) } @@ -120,6 +124,8 @@ pub mod pallet { } } + Self::deposit_event(Event::BarrierListUpdated); + Ok(().into()) } @@ -136,6 +142,8 @@ pub mod pallet { XcmNativeTransfers::::remove(account_id); } + Self::deposit_event(Event::BarrierListUpdated); + Ok(().into()) } } @@ -143,8 +151,14 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - /// An account was created with some free balance. - Endowed, // TODO: actual event + /// TODO: docs + StartUnixTime { + start_unix_time: core::time::Duration, + }, + /// TODO: docs + DailyLimitSet { daily_limit: T::Balance }, + /// TODO: docs + BarrierListUpdated, } #[pallet::error] @@ -268,6 +282,8 @@ impl orml_traits::xcm_transfer::NativeBarrier Date: Tue, 15 Aug 2023 13:04:03 +0300 Subject: [PATCH 16/69] add gensis config, clean up Signed-off-by: Georgi Zlatarev --- pallets/balances/src/lib.rs | 2 +- pallets/native-barrier/src/lib.rs | 43 ++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 1e988b113..b57dbdb78 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -175,7 +175,7 @@ use frame_support::{ Currency, DefensiveSaturating, ExistenceRequirement, ExistenceRequirement::{AllowDeath, KeepAlive}, Get, Imbalance, LockIdentifier, LockableCurrency, NamedReservableCurrency, OnUnbalanced, - ReservableCurrency, SignedImbalance, StoredMap, TryDrop, UnixTime, WithdrawReasons, + ReservableCurrency, SignedImbalance, StoredMap, TryDrop, WithdrawReasons, }, WeakBoundedVec, }; diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 9eef7dca2..fc65d0cec 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -21,6 +21,7 @@ pub mod weights; use codec::{Codec, MaxEncodedLen}; +use core::time::Duration; #[cfg(feature = "std")] use frame_support::traits::GenesisBuild; use frame_support::{ensure, pallet_prelude::DispatchResult, traits::UnixTime}; @@ -71,16 +72,16 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] #[pallet::storage_version(STORAGE_VERSION)] - pub struct Pallet(PhantomData<(T)>); + pub struct Pallet(PhantomData); #[pallet::call] impl Pallet { - /// # + /// TODO: docs #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::set_start_unix_time())] pub fn set_start_unix_time( origin: OriginFor, - start_unix_time: core::time::Duration, + start_unix_time: Duration, ) -> DispatchResult { ensure_root(origin)?; >::set(Some(start_unix_time)); @@ -88,7 +89,7 @@ pub mod pallet { Ok(()) } - /// # + /// TODO: docs #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::set_daily_xcm_limit())] pub fn set_daily_xcm_limit( @@ -139,7 +140,8 @@ pub mod pallet { ensure_root(origin)?; for account_id in accounts { - XcmNativeTransfers::::remove(account_id); + XcmNativeTransfers::::remove(account_id.clone()); + RemainingXcmLimit::::remove(account_id); } Self::deposit_event(Event::BarrierListUpdated); @@ -152,9 +154,7 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// TODO: docs - StartUnixTime { - start_unix_time: core::time::Duration, - }, + StartUnixTime { start_unix_time: Duration }, /// TODO: docs DailyLimitSet { daily_limit: T::Balance }, /// TODO: docs @@ -163,9 +163,9 @@ pub mod pallet { #[pallet::error] pub enum Error { - /// + /// TODO: docs XcmTransfersLimitExceeded, - /// + /// TODO: docs XcmTransfersNotAllowedForAccount, } /// Stores amount of native asset XCM transfers and timestamp of last transfer @@ -187,26 +187,39 @@ pub mod pallet { /// Stores limit value #[pallet::storage] - pub type StartUnixTime = StorageValue<_, core::time::Duration, OptionQuery>; + pub type StartUnixTime = StorageValue<_, Duration, OptionQuery>; #[pallet::genesis_config] pub struct GenesisConfig { - // TODO: real genesis - pub balances: Vec<(T::AccountId, T::Balance)>, + pub barrier_accounts: Vec, + pub daily_limit: T::Balance, } #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { Self { - balances: Default::default(), + barrier_accounts: Default::default(), + daily_limit: Default::default(), } } } #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { - fn build(&self) {} + fn build(&self) { + let now = T::UnixTime::now(); + >::set(Some(now)); + >::set(Some(self.daily_limit)); + for account_id in self.barrier_accounts.iter() { + >::set( + account_id.clone(), + Some((T::Balance::zero(), now.as_secs())), + ); + + >::set(account_id, Some(T::Balance::zero())); + } + } } #[pallet::hooks] From 4b59705e45a69d7910df90591512670ec81bcb18 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 09:51:36 +0300 Subject: [PATCH 17/69] Debugging Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 101 ++++++++++++++++++------------ 1 file changed, 60 insertions(+), 41 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index fc65d0cec..89fc91d1e 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -81,11 +81,11 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::set_start_unix_time())] pub fn set_start_unix_time( origin: OriginFor, - start_unix_time: Duration, + start_unix_time: Option, ) -> DispatchResult { ensure_root(origin)?; - >::set(Some(start_unix_time)); - Self::deposit_event(Event::StartUnixTime { start_unix_time }); + >::set(start_unix_time); + Self::deposit_event(Event::StartUnixTimeSet { start_unix_time }); Ok(()) } @@ -94,11 +94,11 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::set_daily_xcm_limit())] pub fn set_daily_xcm_limit( origin: OriginFor, - daily_xcm_limit: T::Balance, + daily_xcm_limit: Option, ) -> DispatchResult { ensure_root(origin)?; - >::set(Some(daily_xcm_limit)); - Self::deposit_event(Event::DailyLimitSet { + >::set(daily_xcm_limit); + Self::deposit_event(Event::DailyXcmLimitSet { daily_limit: daily_xcm_limit, }); Ok(()) @@ -113,20 +113,29 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - // TODO: unwrap() - let start_time = >::get().unwrap().as_secs(); - for account_id in accounts { - if !XcmNativeTransfers::::contains_key(&account_id) { - XcmNativeTransfers::::insert(&account_id, (T::Balance::zero(), start_time)); - } + if let Some(daily_xcm_limit) = DailyXcmLimit::::get() { + if let Some(start_time) = StartUnixTime::::get() { + for account_id in accounts { + if !XcmNativeTransfers::::contains_key(&account_id) { + XcmNativeTransfers::::insert( + &account_id, + (T::Balance::zero(), start_time.as_secs()), + ); + } + + if !RemainingXcmLimit::::contains_key(&account_id) { + RemainingXcmLimit::::insert(account_id, daily_xcm_limit); + } + } - if !RemainingXcmLimit::::contains_key(&account_id) { - RemainingXcmLimit::::insert(account_id, T::Balance::zero()); + Self::deposit_event(Event::BarrierListUpdated); + } else { + return Err(Error::::StartUnixTimeNotSet.into()); } + } else { + return Err(Error::::XcmDailyLimitNotSet.into()); } - Self::deposit_event(Event::BarrierListUpdated); - Ok(().into()) } @@ -153,10 +162,12 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - /// TODO: docs - StartUnixTime { start_unix_time: Duration }, - /// TODO: docs - DailyLimitSet { daily_limit: T::Balance }, + StartUnixTimeSet { + start_unix_time: Option, + }, + DailyXcmLimitSet { + daily_limit: Option, + }, /// TODO: docs BarrierListUpdated, } @@ -167,6 +178,8 @@ pub mod pallet { XcmTransfersLimitExceeded, /// TODO: docs XcmTransfersNotAllowedForAccount, + StartUnixTimeNotSet, + XcmDailyLimitNotSet, } /// Stores amount of native asset XCM transfers and timestamp of last transfer #[pallet::storage] @@ -217,7 +230,7 @@ pub mod pallet { Some((T::Balance::zero(), now.as_secs())), ); - >::set(account_id, Some(T::Balance::zero())); + >::set(account_id, Some(self.daily_limit)); } } } @@ -225,18 +238,21 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { + // TOD: should i just make the start_unix_time and daily_limit 1 struct if let Some(start_unix_time) = StartUnixTime::::get() { - let now = T::UnixTime::now(); - if start_unix_time <= now { - let days_since_start = - (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); - - // Default is ok, it would only be used the first time - let last_day_processed = >::get().unwrap_or(0); - - if days_since_start > last_day_processed { - Self::reset_remaining_xcm_limit(); - >::put(days_since_start); + if let Some(_) = DailyXcmLimit::::get() { + let now = T::UnixTime::now(); + if start_unix_time <= now { + let days_since_start = + (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); + + // Default is ok, it would only be used the first time + let last_day_processed = >::get().unwrap_or(0); + + if days_since_start > last_day_processed { + Self::reset_remaining_xcm_limit(days_since_start - last_day_processed); + >::put(days_since_start); + } } } } @@ -279,20 +295,21 @@ impl orml_traits::xcm_transfer::NativeBarrier::get(account_id) - .ok_or(Error::::XcmTransfersNotAllowedForAccount)?; + // TODO: this unwrap i s already checked at the start of the function + let (mut transferred, last_transfer) = + XcmNativeTransfers::::get(account_id).unwrap(); let remaining_limit = RemainingXcmLimit::::get(account_id).unwrap_or(transfer_limit); + ensure!( + amount <= remaining_limit, + Error::::XcmTransfersLimitExceeded + ); + if last_transfer < current_period { transferred = T::Balance::zero(); XcmNativeTransfers::::insert(account_id, (transferred, now)); }; - ensure!( - transferred + amount <= remaining_limit, - Error::::XcmTransfersLimitExceeded - ); - // If the ensure didn't return an error, update the native transfers Self::update_xcm_native_transfers(account_id, amount); @@ -324,12 +341,14 @@ impl orml_traits::xcm_transfer::NativeBarrier Pallet { - fn reset_remaining_xcm_limit() { + fn reset_remaining_xcm_limit(unprocessed_days: u64) { if let Some(daily_limit) = >::get() { for (account_id, _) in XcmNativeTransfers::::iter() { let mut remaining_limit = >::get(&account_id).unwrap_or(daily_limit); - remaining_limit += daily_limit; + for _ in 0..unprocessed_days { + remaining_limit += daily_limit; + } >::insert(&account_id, remaining_limit); } } From 3b23239cb10ee396558e9fac1ada792eb3255823 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 12:49:43 +0300 Subject: [PATCH 18/69] Remove xcmnativetransfers storage item, only remainingxcmlimit is needed, add some additional checks Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 73 ++++++++----------------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 89fc91d1e..6332a914a 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -116,13 +116,6 @@ pub mod pallet { if let Some(daily_xcm_limit) = DailyXcmLimit::::get() { if let Some(start_time) = StartUnixTime::::get() { for account_id in accounts { - if !XcmNativeTransfers::::contains_key(&account_id) { - XcmNativeTransfers::::insert( - &account_id, - (T::Balance::zero(), start_time.as_secs()), - ); - } - if !RemainingXcmLimit::::contains_key(&account_id) { RemainingXcmLimit::::insert(account_id, daily_xcm_limit); } @@ -149,7 +142,6 @@ pub mod pallet { ensure_root(origin)?; for account_id in accounts { - XcmNativeTransfers::::remove(account_id.clone()); RemainingXcmLimit::::remove(account_id); } @@ -181,10 +173,6 @@ pub mod pallet { StartUnixTimeNotSet, XcmDailyLimitNotSet, } - /// Stores amount of native asset XCM transfers and timestamp of last transfer - #[pallet::storage] - pub type XcmNativeTransfers = - StorageMap<_, Blake2_128Concat, T::AccountId, (T::Balance, u64), OptionQuery>; /// Stores limit value #[pallet::storage] @@ -225,11 +213,6 @@ pub mod pallet { >::set(Some(now)); >::set(Some(self.daily_limit)); for account_id in self.barrier_accounts.iter() { - >::set( - account_id.clone(), - Some((T::Balance::zero(), now.as_secs())), - ); - >::set(account_id, Some(self.daily_limit)); } } @@ -238,7 +221,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { - // TOD: should i just make the start_unix_time and daily_limit 1 struct + // TODO: should i just make the start_unix_time and daily_limit 1 struct if let Some(start_unix_time) = StartUnixTime::::get() { if let Some(_) = DailyXcmLimit::::get() { let now = T::UnixTime::now(); @@ -246,10 +229,10 @@ pub mod pallet { let days_since_start = (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); - // Default is ok, it would only be used the first time + // Default 0 is ok, it would only be used the first time let last_day_processed = >::get().unwrap_or(0); - if days_since_start > last_day_processed { + if days_since_start > last_day_processed || days_since_start == 0 { Self::reset_remaining_xcm_limit(days_since_start - last_day_processed); >::put(days_since_start); } @@ -280,39 +263,27 @@ impl GenesisConfig { } } -const XCM_LIMIT_PERIOD_IN_SEC: u64 = 86400; // 1 day - impl orml_traits::xcm_transfer::NativeBarrier for Pallet { fn ensure_xcm_transfer_limit_not_exceeded( account_id: &T::AccountId, amount: T::Balance, ) -> DispatchResult { - if let Some(transfer_limit) = DailyXcmLimit::::get() { - // The address is not in the barrier list, so we don't care about it - if >::get(account_id).is_none() { - return Ok(()); + if let Some(_) = DailyXcmLimit::::get() { + if let Some(start_unix_time) = >::get() { + let now = T::UnixTime::now(); + if start_unix_time <= now { + if let Some(remaining_limit) = RemainingXcmLimit::::get(account_id) { + ensure!( + amount <= remaining_limit, + Error::::XcmTransfersLimitExceeded + ); + + // If the ensure didn't return an error, update the native transfers + Self::update_xcm_native_transfers(account_id, amount); + } + } } - let now = T::UnixTime::now().as_secs(); - let current_period = (now / XCM_LIMIT_PERIOD_IN_SEC) * XCM_LIMIT_PERIOD_IN_SEC; - // TODO: this unwrap i s already checked at the start of the function - let (mut transferred, last_transfer) = - XcmNativeTransfers::::get(account_id).unwrap(); - let remaining_limit = RemainingXcmLimit::::get(account_id).unwrap_or(transfer_limit); - - ensure!( - amount <= remaining_limit, - Error::::XcmTransfersLimitExceeded - ); - - if last_transfer < current_period { - transferred = T::Balance::zero(); - XcmNativeTransfers::::insert(account_id, (transferred, now)); - }; - - // If the ensure didn't return an error, update the native transfers - Self::update_xcm_native_transfers(account_id, amount); - // TODO: maybe add event here that the transfers were updated } @@ -320,14 +291,6 @@ impl orml_traits::xcm_transfer::NativeBarrier>::mutate_exists(account_id, |maybe_transfer| match maybe_transfer { - Some((current_amount, last_transfer)) => { - *current_amount = *current_amount + amount; - *last_transfer = T::UnixTime::now().as_secs(); - } - None => {} - }); - >::mutate_exists( account_id, |maybe_remainder| match maybe_remainder { @@ -343,7 +306,7 @@ impl orml_traits::xcm_transfer::NativeBarrier Pallet { fn reset_remaining_xcm_limit(unprocessed_days: u64) { if let Some(daily_limit) = >::get() { - for (account_id, _) in XcmNativeTransfers::::iter() { + for (account_id, _) in RemainingXcmLimit::::iter() { let mut remaining_limit = >::get(&account_id).unwrap_or(daily_limit); for _ in 0..unprocessed_days { From d554ccf25b71b36e020317f12ea48588dcfda3b5 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:01:57 +0300 Subject: [PATCH 19/69] fmt and remove unnecessary imports Signed-off-by: Georgi Zlatarev --- Cargo.lock | 1 + pallets/balances/Cargo.toml | 2 +- pallets/manta-pay/Cargo.toml | 2 +- pallets/native-barrier/Cargo.toml | 15 ++++----------- pallets/native-barrier/src/lib.rs | 4 ++-- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13729d1d3..0e6d9f3ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7265,6 +7265,7 @@ dependencies = [ name = "pallet-native-barrier" version = "4.4.0" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index 3e54fb8f0..932db0595 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -42,7 +42,7 @@ std = [ "sp-runtime/std", "sp-std/std", "pallet-native-barrier/std", - "orml-traits/std" + "orml-traits/std" ] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime", "pallet-native-barrier/try-runtime"] diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index c3e44299b..c4df5cb04 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -74,7 +74,7 @@ std = [ "manta-pay/std", "manta-support/std", "pallet-native-barrier/std", - "orml-traits/std" + "orml-traits/std" ] # Precompute Benchmark Transactions diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 425ddb525..07f970271 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -12,9 +12,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } -#log = { version = "0.4.17", default-features = false } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -#frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } +frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } @@ -22,25 +21,19 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } -[dev-dependencies] -#pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -#sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -#sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } - [features] default = ["std"] std = [ "codec/std", - #"frame-benchmarking?/std", + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", - #"log/std", "scale-info/std", "sp-runtime/std", "sp-std/std", - "orml-traits/std" + "orml-traits/std" ] runtime-benchmarks = [ - #"frame-benchmarking/runtime-benchmarks" + "frame-benchmarking/runtime-benchmarks" ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 6332a914a..b7ce8cf6e 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -28,7 +28,7 @@ use frame_support::{ensure, pallet_prelude::DispatchResult, traits::UnixTime}; pub use pallet::*; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Zero}, + traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}, FixedPointOperand, Saturating, }; use sp_std::{fmt::Debug, prelude::*}; @@ -114,7 +114,7 @@ pub mod pallet { ensure_root(origin)?; if let Some(daily_xcm_limit) = DailyXcmLimit::::get() { - if let Some(start_time) = StartUnixTime::::get() { + if let Some(_) = StartUnixTime::::get() { for account_id in accounts { if !RemainingXcmLimit::::contains_key(&account_id) { RemainingXcmLimit::::insert(account_id, daily_xcm_limit); From cde01c133b73a672ad6297ec2da7be4d51b53b85 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:08:41 +0300 Subject: [PATCH 20/69] Change headers Signed-off-by: Georgi Zlatarev --- pallets/balances/src/benchmarking.rs | 31 +++++++++++----------- pallets/balances/src/lib.rs | 27 +++++++++---------- pallets/balances/src/tests.rs | 27 +++++++++---------- pallets/balances/src/tests_composite.rs | 27 +++++++++---------- pallets/balances/src/tests_local.rs | 27 +++++++++---------- pallets/balances/src/tests_reentrancy.rs | 27 +++++++++---------- pallets/balances/src/weights.rs | 27 +++++++++---------- pallets/native-barrier/src/benchmarking.rs | 31 +++++++++++----------- pallets/native-barrier/src/weights.rs | 29 ++++++++++---------- 9 files changed, 123 insertions(+), 130 deletions(-) diff --git a/pallets/balances/src/benchmarking.rs b/pallets/balances/src/benchmarking.rs index a310d46d7..60081adde 100644 --- a/pallets/balances/src/benchmarking.rs +++ b/pallets/balances/src/benchmarking.rs @@ -1,21 +1,20 @@ -// This file is part of Substrate. - -// Copyright (C) 2020-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// 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. - -//! Balances pallet benchmarking. +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . +// +//! # Native Barrier Pallet benchmarking. #![cfg(feature = "runtime-benchmarks")] diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index b57dbdb78..05af552a3 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -1,19 +1,18 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// 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. +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . //! # Balances Pallet //! diff --git a/pallets/balances/src/tests.rs b/pallets/balances/src/tests.rs index 433e6be71..91f9606c3 100644 --- a/pallets/balances/src/tests.rs +++ b/pallets/balances/src/tests.rs @@ -1,19 +1,18 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// 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. +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . //! Macro for creating the tests for the module. diff --git a/pallets/balances/src/tests_composite.rs b/pallets/balances/src/tests_composite.rs index a2d7593b1..e8a96bfbd 100644 --- a/pallets/balances/src/tests_composite.rs +++ b/pallets/balances/src/tests_composite.rs @@ -1,19 +1,18 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// 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. +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . //! Test utilities diff --git a/pallets/balances/src/tests_local.rs b/pallets/balances/src/tests_local.rs index cb69aed4e..4eb179dc5 100644 --- a/pallets/balances/src/tests_local.rs +++ b/pallets/balances/src/tests_local.rs @@ -1,19 +1,18 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// 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. +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . //! Test utilities diff --git a/pallets/balances/src/tests_reentrancy.rs b/pallets/balances/src/tests_reentrancy.rs index 89ff5fb50..53cad4d7c 100644 --- a/pallets/balances/src/tests_reentrancy.rs +++ b/pallets/balances/src/tests_reentrancy.rs @@ -1,19 +1,18 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// 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. +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . //! Test setup for potential reentracy and lost updates of nested mutations. diff --git a/pallets/balances/src/weights.rs b/pallets/balances/src/weights.rs index 6324745fd..b5579e3c0 100644 --- a/pallets/balances/src/weights.rs +++ b/pallets/balances/src/weights.rs @@ -1,19 +1,18 @@ -// This file is part of Substrate. - -// Copyright (C) 2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// 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. +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . //! Autogenerated weights for pallet_balances //! diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 164d10d44..eba8c7a39 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -1,21 +1,20 @@ -// // This file is part of Substrate. - -// // Copyright (C) 2020-2022 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 +// // Copyright 2020-2023 Manta Network. +// // This file is part of Manta. // // -// // http://www.apache.org/licenses/LICENSE-2.0 +// // Manta is free software: you can redistribute it and/or modify +// // it under the terms of the GNU General Public License as published by +// // the Free Software Foundation, either version 3 of the License, or +// // (at your option) any later version. // // -// // 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. - -// //! Balances pallet benchmarking. +// // Manta is distributed in the hope that it will be useful, +// // but WITHOUT ANY WARRANTY; without even the implied warranty of +// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// // GNU General Public License for more details. +// // +// // You should have received a copy of the GNU General Public License +// // along with Manta. If not, see . +// // +// //! # Native Barrier Pallet benchmarking. // #![cfg(feature = "runtime-benchmarks")] diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index 432b89c76..fa4305e19 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -1,19 +1,20 @@ -// This file is part of Substrate. - -// Copyright (C) 2022 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 +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// http://www.apache.org/licenses/LICENSE-2.0 +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . // -// 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. +//! # Native Barrier Pallet //! Autogenerated weights for pallet_balances //! From 744b134bd55b23dc1d4bbcd487b413888685ff9d Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:12:51 +0300 Subject: [PATCH 21/69] storage docs Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index b7ce8cf6e..db6f1a684 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -174,19 +174,20 @@ pub mod pallet { XcmDailyLimitNotSet, } - /// Stores limit value + /// Stores daily limit value #[pallet::storage] pub type DailyXcmLimit = StorageValue<_, T::Balance, OptionQuery>; + /// Stores remaining limit for each account. Skipped days are accumulated. #[pallet::storage] pub type RemainingXcmLimit = StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; - /// Stores limit value + /// Caches the last processed day, used to check for start of new days #[pallet::storage] pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; - /// Stores limit value + /// Stores starting unix time for the native barrier logic #[pallet::storage] pub type StartUnixTime = StorageValue<_, Duration, OptionQuery>; From 785982a9560bd390ec3c5f107530bb754509678e Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:13:28 +0300 Subject: [PATCH 22/69] remove unnecessary error Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index db6f1a684..a4fb9628d 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -168,8 +168,6 @@ pub mod pallet { pub enum Error { /// TODO: docs XcmTransfersLimitExceeded, - /// TODO: docs - XcmTransfersNotAllowedForAccount, StartUnixTimeNotSet, XcmDailyLimitNotSet, } From 53f808c17eebfdd96170402b208f399d68dc99fe Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:15:04 +0300 Subject: [PATCH 23/69] fix errors docs Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index a4fb9628d..a4f38e77d 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -166,7 +166,6 @@ pub mod pallet { #[pallet::error] pub enum Error { - /// TODO: docs XcmTransfersLimitExceeded, StartUnixTimeNotSet, XcmDailyLimitNotSet, From e9997fe0f114ae3dacb3ef4995a6b2196af2efd2 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:22:05 +0300 Subject: [PATCH 24/69] Clean up Signed-off-by: Georgi Zlatarev --- runtime/manta/src/xcm_config.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/manta/src/xcm_config.rs b/runtime/manta/src/xcm_config.rs index de4c347f8..2c0cb660e 100644 --- a/runtime/manta/src/xcm_config.rs +++ b/runtime/manta/src/xcm_config.rs @@ -333,7 +333,6 @@ impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { CurrencyIdtoMultiLocation::>::convert( currency_id.clone(), ); - //asset_location == MultiLocation::from(NativeAssetLocation::get()) asset_location == NativeAssetLocation::get().into() || asset_location == Some(Here.into()) } } From 527e20278d7744c30a64ab7dfaf751fef4131b77 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:33:40 +0300 Subject: [PATCH 25/69] Extrinsics docs Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index a4f38e77d..abc475b98 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -76,7 +76,8 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// TODO: docs + /// Sets the start unix time for the barrier logic. + /// Can be in the past or the future. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::set_start_unix_time())] pub fn set_start_unix_time( @@ -89,7 +90,8 @@ pub mod pallet { Ok(()) } - /// TODO: docs + /// Sets the daily limit amount. + /// Can be set to None to turn off the barrier. #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::set_daily_xcm_limit())] pub fn set_daily_xcm_limit( @@ -104,7 +106,9 @@ pub mod pallet { Ok(()) } - /// Add `accounts` to barrier to make them have limited xcm native transfers + /// Add `accounts` to barrier to make them have limited native transfers + /// Sets the Date: Wed, 16 Aug 2023 16:48:07 +0300 Subject: [PATCH 26/69] Events docs , add remove from barrier event and use iter() instead of for loops for iterating the accounts Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index abc475b98..32c2997f9 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -119,13 +119,13 @@ pub mod pallet { if let Some(daily_xcm_limit) = DailyXcmLimit::::get() { if let Some(_) = StartUnixTime::::get() { - for account_id in accounts { + for account_id in accounts.iter() { if !RemainingXcmLimit::::contains_key(&account_id) { RemainingXcmLimit::::insert(account_id, daily_xcm_limit); } } - Self::deposit_event(Event::BarrierListUpdated); + Self::deposit_event(Event::AccountsAddedToBarrier { accounts }); } else { return Err(Error::::StartUnixTimeNotSet.into()); } @@ -145,11 +145,11 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - for account_id in accounts { + for account_id in accounts.iter() { RemainingXcmLimit::::remove(account_id); } - Self::deposit_event(Event::BarrierListUpdated); + Self::deposit_event(Event::AccountsRemovedFromBarrier { accounts }); Ok(().into()) } @@ -158,14 +158,10 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - StartUnixTimeSet { - start_unix_time: Option, - }, - DailyXcmLimitSet { - daily_limit: Option, - }, - /// TODO: docs - BarrierListUpdated, + StartUnixTimeSet { start_unix_time: Option }, + DailyXcmLimitSet { daily_limit: Option }, + AccountsAddedToBarrier { accounts: Vec }, + AccountsRemovedFromBarrier { accounts: Vec }, } #[pallet::error] From 297177d327593161a51a7218490b77a15cc3da22 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 16:49:02 +0300 Subject: [PATCH 27/69] Clean up todos Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 32c2997f9..47a8cfebf 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -281,8 +281,6 @@ impl orml_traits::xcm_transfer::NativeBarrier Date: Wed, 16 Aug 2023 16:55:31 +0300 Subject: [PATCH 28/69] Clean up todos in native-barrier pallet Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 4 +--- pallets/native-barrier/src/weights.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 47a8cfebf..64dbcfd4a 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -219,7 +219,6 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { - // TODO: should i just make the start_unix_time and daily_limit 1 struct if let Some(start_unix_time) = StartUnixTime::::get() { if let Some(_) = DailyXcmLimit::::get() { let now = T::UnixTime::now(); @@ -238,8 +237,7 @@ pub mod pallet { } } - //T::WeightInfo::on_initialize() - Weight::from_ref_time(0) // TODO: use the commented out line + T::WeightInfo::on_initialize() } } } diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index fa4305e19..b93da5fa0 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -49,6 +49,8 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_balances. pub trait WeightInfo { + fn on_initialize() -> Weight; + fn set_start_unix_time() -> Weight; fn set_daily_xcm_limit() -> Weight; @@ -61,6 +63,15 @@ pub trait WeightInfo { /// Weights for pallet_balances using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 5_170 nanoseconds. + Weight::from_ref_time(5_433_000) + .saturating_add(T::DbWeight::get().reads(2)) + } + // Storage: System Account (r:1 w:1) fn set_start_unix_time() -> Weight { // Minimum execution time: 48_134 nanoseconds. @@ -94,6 +105,11 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { + fn on_initialize() -> Weight { + Weight::from_ref_time(5_433_000) + .saturating_add(RocksDbWeight::get().reads(2)) + } + // Storage: System Account (r:1 w:1) fn set_start_unix_time() -> Weight { // Minimum execution time: 48_134 nanoseconds. From c0444e8a8c9ace7d064e014daf3744426180b06e Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 16 Aug 2023 17:17:50 +0300 Subject: [PATCH 29/69] fmt Signed-off-by: Georgi Zlatarev --- pallets/balances/Cargo.toml | 41 +++++++++---------- pallets/collator-selection/Cargo.toml | 2 +- pallets/manta-pay/Cargo.toml | 6 +-- pallets/manta-sbt/Cargo.toml | 2 +- pallets/name-service/Cargo.toml | 2 +- pallets/native-barrier/Cargo.toml | 24 +++++------ pallets/pallet-lottery/Cargo.toml | 2 +- pallets/randomness/Cargo.toml | 2 +- pallets/tx-pause/Cargo.toml | 2 +- pallets/vesting/Cargo.toml | 2 +- runtime/calamari/Cargo.toml | 2 +- .../src/xcm_mock/parachain.rs | 1 - runtime/manta/Cargo.toml | 4 +- 13 files changed, 45 insertions(+), 47 deletions(-) diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index 932db0595..bb7d85592 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -1,29 +1,28 @@ [package] -name = "pallet-balances" -version = "4.0.0-dev" -authors = ["Parity Technologies "] +authors = ['Manta Network'] edition = "2021" -license = "Apache-2.0" -homepage = "https://substrate.io" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME pallet to manage balances" +homepage = 'https://manta.network' +license = 'GPL-3.0' +name = "pallet-balances" readme = "README.md" +repository = 'https://github.com/Manta-Network/Manta/' +version = '4.4.0' [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } -log = { version = "0.4.17", default-features = false } -scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +log = { version = "0.4.17", default-features = false } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -pallet-native-barrier = { path = '../native-barrier', default-features = false } orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } @@ -32,17 +31,17 @@ sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkado [features] default = ["std"] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] std = [ - "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "log/std", - "scale-info/std", - "sp-runtime/std", - "sp-std/std", - "pallet-native-barrier/std", - "orml-traits/std" + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "sp-runtime/std", + "sp-std/std", + "pallet-native-barrier/std", + "orml-traits/std", ] -runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime", "pallet-native-barrier/try-runtime"] diff --git a/pallets/collator-selection/Cargo.toml b/pallets/collator-selection/Cargo.toml index 37fbce1e3..b6778057e 100644 --- a/pallets/collator-selection/Cargo.toml +++ b/pallets/collator-selection/Cargo.toml @@ -32,6 +32,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] manta-primitives = { path = "../../primitives/manta" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } @@ -40,7 +41,6 @@ sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polka sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-tracing = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ['std'] diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index c4df5cb04..12198cba2 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -48,7 +48,7 @@ runtime-benchmarks = [ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", - "pallet-native-barrier/try-runtime" + "pallet-native-barrier/try-runtime", ] # Serde Serialization @@ -74,7 +74,7 @@ std = [ "manta-pay/std", "manta-support/std", "pallet-native-barrier/std", - "orml-traits/std" + "orml-traits/std", ] # Precompute Benchmark Transactions @@ -122,8 +122,8 @@ manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5 manta-primitives = { path = "../../primitives/manta", default-features = false } manta-support = { package = "pallet-manta-support", path = "../manta-support", default-features = false } manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", default-features = false } -pallet-native-barrier = { path = '../native-barrier', default-features = false } orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] lazy_static = "1.4.0" diff --git a/pallets/manta-sbt/Cargo.toml b/pallets/manta-sbt/Cargo.toml index a8f4dfccb..db2271ad0 100644 --- a/pallets/manta-sbt/Cargo.toml +++ b/pallets/manta-sbt/Cargo.toml @@ -127,6 +127,7 @@ manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0. lazy_static = "1.4.0" manta-crypto = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["getrandom"] } manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["groth16", "parameters", "scale", "download", "test"] } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-asset-manager = { path = "../asset-manager" } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } @@ -135,4 +136,3 @@ pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch pallet-tx-pause = { path = "../tx-pause" } tempfile = "3.3.0" xcm = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } diff --git a/pallets/name-service/Cargo.toml b/pallets/name-service/Cargo.toml index 5cfbc8d8d..d45eea146 100644 --- a/pallets/name-service/Cargo.toml +++ b/pallets/name-service/Cargo.toml @@ -22,10 +22,10 @@ sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "po sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false } [dev-dependencies] +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 07f970271..c0cbcb773 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -12,10 +12,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } -scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } frame-support = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } frame-system = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } @@ -23,17 +23,17 @@ orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-libr [features] default = ["std"] -std = [ - "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "scale-info/std", - "sp-runtime/std", - "sp-std/std", - "orml-traits/std" -] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks" + "frame-benchmarking/runtime-benchmarks", +] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", + "sp-runtime/std", + "sp-std/std", + "orml-traits/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/pallet-lottery/Cargo.toml b/pallets/pallet-lottery/Cargo.toml index 62ac552fe..840cf5aa1 100644 --- a/pallets/pallet-lottery/Cargo.toml +++ b/pallets/pallet-lottery/Cargo.toml @@ -40,6 +40,7 @@ rand = { version = "0.8.5", default-features = false, optional = true } calamari-runtime = { path = "../../runtime/calamari", default-features = false } lazy_static = "1.4.0" manta-collator-selection = { path = "../collator-selection", default-features = false } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-preimage = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-randomness = { path = '../randomness', default-features = false } @@ -48,7 +49,6 @@ pallet-transaction-payment = { git = "https://github.com/paritytech/substrate.gi rand = "0.8" similar-asserts = "1.1.0" sp-staking = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/randomness/Cargo.toml b/pallets/randomness/Cargo.toml index 851c97d5a..5c616a6bb 100644 --- a/pallets/randomness/Cargo.toml +++ b/pallets/randomness/Cargo.toml @@ -27,8 +27,8 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkad [dev-dependencies] derive_more = "0.99" -pallet-balances = { path = "../balances", features = ["std"]} orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +pallet-balances = { path = "../balances", features = ["std"] } [features] default = ["std"] diff --git a/pallets/tx-pause/Cargo.toml b/pallets/tx-pause/Cargo.toml index ce6ced12d..a1020baa4 100644 --- a/pallets/tx-pause/Cargo.toml +++ b/pallets/tx-pause/Cargo.toml @@ -18,10 +18,10 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad [dev-dependencies] manta-primitives = { path = '../../primitives/manta' } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/vesting/Cargo.toml b/pallets/vesting/Cargo.toml index aeb5b8a52..8aca47098 100644 --- a/pallets/vesting/Cargo.toml +++ b/pallets/vesting/Cargo.toml @@ -22,11 +22,11 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] chrono = "0.4" manta-primitives = { path = "../../primitives/manta" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index ec9b65dda..628f3a76e 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -100,12 +100,12 @@ pallet-lottery = { path = '../../pallets/pallet-lottery', default-features = fal pallet-manta-pay = { path = '../../pallets/manta-pay', default-features = false, features = ["runtime"] } pallet-manta-sbt = { path = '../../pallets/manta-sbt', default-features = false, features = ["runtime"] } pallet-name-service = { path = '../../pallets/name-service', default-features = false } +pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } pallet-parachain-staking = { path = '../../pallets/parachain-staking', default-features = false } pallet-randomness = { path = '../../pallets/randomness', default-features = false } pallet-tx-pause = { path = '../../pallets/tx-pause', default-features = false } runtime-common = { path = '../common', default-features = false } session-key-primitives = { path = '../../primitives/session-keys', default-features = false } -pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } # Third party (vendored) dependencies orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } diff --git a/runtime/integration-tests/src/xcm_mock/parachain.rs b/runtime/integration-tests/src/xcm_mock/parachain.rs index 81601fc6a..272f98e62 100644 --- a/runtime/integration-tests/src/xcm_mock/parachain.rs +++ b/runtime/integration-tests/src/xcm_mock/parachain.rs @@ -701,7 +701,6 @@ impl Contains for AssetManager { } } - // The XCM message wrapper wrapper impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index a35ae063c..3825566ff 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -102,12 +102,12 @@ pallet-lottery = { path = '../../pallets/pallet-lottery', default-features = fal pallet-manta-pay = { path = '../../pallets/manta-pay', default-features = false, features = ["runtime"] } pallet-manta-sbt = { path = '../../pallets/manta-sbt', default-features = false, features = ["runtime"] } pallet-name-service = { path = '../../pallets/name-service', default-features = false } +pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } pallet-parachain-staking = { path = '../../pallets/parachain-staking', default-features = false } pallet-randomness = { path = '../../pallets/randomness', default-features = false } pallet-tx-pause = { path = '../../pallets/tx-pause', default-features = false } runtime-common = { path = '../common', default-features = false } session-key-primitives = { path = '../../primitives/session-keys', default-features = false } -pallet-native-barrier = { path = '../../pallets/native-barrier', default-features = false } [dev-dependencies] csv = "1.2.1" @@ -287,7 +287,7 @@ std = [ "zenlink-protocol-runtime-api/std", "pallet-farming/std", "pallet-farming-rpc-runtime-api/std", - "pallet-native-barrier/std" + "pallet-native-barrier/std", ] # A feature that should be enabled when the runtime should be build for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm From ff9261323d2e5c4bcfcc7c2c5eedf9fa03f9844c Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 17 Aug 2023 10:46:36 +0300 Subject: [PATCH 30/69] Add native-barrier benchmak code Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/README.md | 122 ++++++++ pallets/native-barrier/src/benchmarking.rs | 324 +++++++-------------- pallets/native-barrier/src/lib.rs | 7 +- pallets/native-barrier/src/weights.rs | 6 +- 4 files changed, 233 insertions(+), 226 deletions(-) create mode 100644 pallets/native-barrier/README.md diff --git a/pallets/native-barrier/README.md b/pallets/native-barrier/README.md new file mode 100644 index 000000000..93e424a89 --- /dev/null +++ b/pallets/native-barrier/README.md @@ -0,0 +1,122 @@ +# Balances Module + +The Balances module provides functionality for handling accounts and balances. + +- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) +- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) +- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) + +## Overview + +The Balances module provides functions for: + +- Getting and setting free balances. +- Retrieving total, reserved and unreserved balances. +- Repatriating a reserved balance to a beneficiary account that exists. +- Transferring a balance between accounts (when not reserved). +- Slashing an account balance. +- Account creation and removal. +- Managing total issuance. +- Setting and managing locks. + +### Terminology + +- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents +"dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) + fall below this, then the account is said to be dead; and it loses its functionality as well as any + prior history and all information on it is removed from the chain's state. + No account should ever have a total balance that is strictly between 0 and the existential + deposit (exclusive). If this ever happens, it indicates either a bug in this module or an + erroneous raw mutation of storage. + +- **Total Issuance:** The total number of units in existence in a system. + +- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its +total balance has become zero (or, strictly speaking, less than the Existential Deposit). + +- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only + balance that matters for most operations. + +- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. + Reserved balance can still be slashed, but only after all the free balance has been slashed. + +- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting +(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will +return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is +simply dropped, it should automatically maintain any book-keeping such as total issuance.) + +- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple +locks always operate over the same funds, so they "overlay" rather than "stack". + +### Implementations + +The Balances module provides implementations for the following traits. If these traits provide the functionality +that you need, then you can avoid coupling with the Balances module. + +- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing with a +fungible assets system. +- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): +Functions for dealing with assets that can be reserved from an account. +- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions for +dealing with accounts that allow liquidity restrictions. +- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling +imbalances between total issuance in the system and account balances. Must be used when a function +creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to say whether a +given account is unused. + +## Interface + +### Dispatchable Functions + +- `transfer` - Transfer some liquid free balance to another account. +- `set_balance` - Set the balances of a given account. The origin of this call must be root. + +## Usage + +The following examples show how to use the Balances module in your custom module. + +### Examples from the FRAME + +The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: + +```rust +use frame_support::traits::Currency; + +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; + +``` + +The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: + +```rust +use frame_support::traits::{WithdrawReasons, LockableCurrency}; +use sp_runtime::traits::Bounded; +pub trait Config: frame_system::Config { + type Currency: LockableCurrency; +} + +fn update_ledger( + controller: &T::AccountId, + ledger: &StakingLedger +) { + T::Currency::set_lock( + STAKING_ID, + &ledger.stash, + ledger.total, + WithdrawReasons::all() + ); + // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +} +``` + +## Genesis config + +The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). + +## Assumptions + +* Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. + +License: Apache-2.0 diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index eba8c7a39..435d5fd32 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -1,221 +1,103 @@ -// // Copyright 2020-2023 Manta Network. -// // This file is part of Manta. -// // -// // Manta is free software: you can redistribute it and/or modify -// // it under the terms of the GNU General Public License as published by -// // the Free Software Foundation, either version 3 of the License, or -// // (at your option) any later version. -// // -// // Manta is distributed in the hope that it will be useful, -// // but WITHOUT ANY WARRANTY; without even the implied warranty of -// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// // GNU General Public License for more details. -// // -// // You should have received a copy of the GNU General Public License -// // along with Manta. If not, see . -// // -// //! # Native Barrier Pallet benchmarking. - -// #![cfg(feature = "runtime-benchmarks")] - -// use super::*; - -// use frame_benchmarking::{account, benchmarks_instance_pallet, whitelisted_caller}; -// use frame_system::RawOrigin; -// use sp_runtime::traits::Bounded; - -// use crate::Pallet as Balances; - -// const SEED: u32 = 0; -// // existential deposit multiplier -// const ED_MULTIPLIER: u32 = 10; - -// benchmarks_instance_pallet! { -// // Benchmark `transfer` extrinsic with the worst possible conditions: -// // * Transfer will kill the sender account. -// // * Transfer will create the recipient account. -// transfer { -// let existential_deposit = T::ExistentialDeposit::get(); -// let caller = whitelisted_caller(); - -// // Give some multiple of the existential deposit -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - -// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, -// // and reap this user. -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); -// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); -// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // Benchmark `transfer` with the best possible condition: -// // * Both accounts exist and will continue to exist. -// #[extra] -// transfer_best_case { -// let caller = whitelisted_caller(); -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - -// // Give the sender account max funds for transfer (their account will never reasonably be killed). -// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); - -// // Give the recipient account existential deposit (thus their account already exists). -// let existential_deposit = T::ExistentialDeposit::get(); -// let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); -// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert!(!Balances::::free_balance(&caller).is_zero()); -// assert!(!Balances::::free_balance(&recipient).is_zero()); -// } - -// // Benchmark `transfer_keep_alive` with the worst possible condition: -// // * The recipient account is created. -// transfer_keep_alive { -// let caller = whitelisted_caller(); -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - -// // Give the sender account max funds, thus a transfer will not kill account. -// let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); -// let existential_deposit = T::ExistentialDeposit::get(); -// let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert!(!Balances::::free_balance(&caller).is_zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // Benchmark `set_balance` coming from ROOT account. This always creates an account. -// set_balance_creating { -// let user: T::AccountId = account("user", 0, SEED); -// let user_lookup = T::Lookup::unlookup(user.clone()); - -// // Give the user some initial balance. -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); -// }: set_balance(RawOrigin::Root, user_lookup, balance_amount, balance_amount) -// verify { -// assert_eq!(Balances::::free_balance(&user), balance_amount); -// assert_eq!(Balances::::reserved_balance(&user), balance_amount); -// } - -// // Benchmark `set_balance` coming from ROOT account. This always kills an account. -// set_balance_killing { -// let user: T::AccountId = account("user", 0, SEED); -// let user_lookup = T::Lookup::unlookup(user.clone()); - -// // Give the user some initial balance. -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); -// }: set_balance(RawOrigin::Root, user_lookup, Zero::zero(), Zero::zero()) -// verify { -// assert!(Balances::::free_balance(&user).is_zero()); -// } - -// // Benchmark `force_transfer` extrinsic with the worst possible conditions: -// // * Transfer will kill the sender account. -// // * Transfer will create the recipient account. -// force_transfer { -// let existential_deposit = T::ExistentialDeposit::get(); -// let source: T::AccountId = account("source", 0, SEED); -// let source_lookup = T::Lookup::unlookup(source.clone()); - -// // Give some multiple of the existential deposit -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&source, balance); - -// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); -// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); -// }: force_transfer(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount) -// verify { -// assert_eq!(Balances::::free_balance(&source), Zero::zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // This benchmark performs the same operation as `transfer` in the worst case scenario, -// // but additionally introduces many new users into the storage, increasing the the merkle -// // trie and PoV size. -// #[extra] -// transfer_increasing_users { -// // 1_000 is not very much, but this upper bound can be controlled by the CLI. -// let u in 0 .. 1_000; -// let existential_deposit = T::ExistentialDeposit::get(); -// let caller = whitelisted_caller(); - -// // Give some multiple of the existential deposit -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - -// // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, -// // and reap this user. -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); -// let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); - -// // Create a bunch of users in storage. -// for i in 0 .. u { -// // The `account` function uses `blake2_256` to generate unique accounts, so these -// // should be quite random and evenly distributed in the trie. -// let new_user: T::AccountId = account("new_user", i, SEED); -// let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); -// } -// }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) -// verify { -// assert_eq!(Balances::::free_balance(&caller), Zero::zero()); -// assert_eq!(Balances::::free_balance(&recipient), transfer_amount); -// } - -// // Benchmark `transfer_all` with the worst possible condition: -// // * The recipient account is created -// // * The sender is killed -// transfer_all { -// let caller = whitelisted_caller(); -// let recipient: T::AccountId = account("recipient", 0, SEED); -// let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - -// // Give some multiple of the existential deposit -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&caller, balance); -// }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, false) -// verify { -// assert!(Balances::::free_balance(&caller).is_zero()); -// assert_eq!(Balances::::free_balance(&recipient), balance); -// } - -// force_unreserve { -// let user: T::AccountId = account("user", 0, SEED); -// let user_lookup = T::Lookup::unlookup(user.clone()); - -// // Give some multiple of the existential deposit -// let existential_deposit = T::ExistentialDeposit::get(); -// let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); -// let _ = as Currency<_>>::make_free_balance_be(&user, balance); - -// // Reserve the balance -// as ReservableCurrency<_>>::reserve(&user, balance)?; -// assert_eq!(Balances::::reserved_balance(&user), balance); -// assert!(Balances::::free_balance(&user).is_zero()); - -// }: _(RawOrigin::Root, user_lookup, balance) -// verify { -// assert!(Balances::::reserved_balance(&user).is_zero()); -// assert_eq!(Balances::::free_balance(&user), balance); -// } - -// impl_benchmark_test_suite!( -// Balances, -// crate::tests_composite::ExtBuilder::default().build(), -// crate::tests_composite::Test, -// ) -// } +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . +// +//! # Native Barrier Pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use crate::Pallet as NativeBarrier; +use core::time::Duration; +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_support::traits::UnixTime; +use frame_system::RawOrigin; +use sp_runtime::traits::{Bounded, Zero}; + +const SEED: u32 = 0; +// existential deposit multiplier +const ED_MULTIPLIER: u32 = 10; + +benchmarks! { + // + set_start_unix_time { + let caller: T::AccountId = whitelisted_caller(); + let start_unix_time = Duration::default(); + }: set_start_unix_time(RawOrigin::Root, Some(start_unix_time)) + verify { + assert_eq!(NativeBarrier::::get_start_unix_time().unwrap(), start_unix_time); + } + + // + set_daily_xcm_limit { + let caller: T::AccountId = whitelisted_caller(); + let daily_limit = T::Balance::zero(); + }: set_daily_xcm_limit(RawOrigin::Root, Some(daily_limit)) + verify { + assert_eq!(NativeBarrier::::get_daily_xcm_limit().unwrap(), daily_limit); + } + + // + add_accounts_to_native_barrier { + let caller: T::AccountId = whitelisted_caller(); + let daily_limit = T::Balance::zero(); + NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit)); + let barrier_addresses: Vec = vec![ + account("address_0", 0, SEED), + account("address_1", 0, SEED), + account("address_2", 0, SEED), + account("address_3", 0, SEED), + account("address_4", 0, SEED) + ]; + let daily_limit = T::Balance::zero(); + }: add_accounts_to_native_barrier(RawOrigin::Root, barrier_addresses) + verify { + for (account_id, _) in RemainingXcmLimit::::iter() { + assert_eq!(RemainingXcmLimit::::get(account_id).unwrap(), daily_limit); + } + } + + // + remove_accounts_from_native_barrier { + let caller: T::AccountId = whitelisted_caller(); + let daily_limit = T::Balance::zero(); + NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit)); + let barrier_addresses: Vec = vec![ + account("address_0", 0, SEED), + account("address_1", 0, SEED), + account("address_2", 0, SEED), + account("address_3", 0, SEED), + account("address_4", 0, SEED) + ]; + let remove_addresses = vec![ + barrier_addresses[0].clone(), + barrier_addresses[2].clone(), + barrier_addresses[4].clone() + ]; + NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses); + }: remove_accounts_from_native_barrier(RawOrigin::Root, remove_addresses) + verify { + assert_eq!(None, RemainingXcmLimit::::get(account::("address_0", 0, SEED))); + assert_eq!(None, RemainingXcmLimit::::get(account::("address_2", 0, SEED))); + assert_eq!(None, RemainingXcmLimit::::get(account::("address_4", 0, SEED))); + } + + // impl_benchmark_test_suite!( + // NativeBarrier, + // crate::tests_composite::ExtBuilder::default().build(), + // crate::tests_composite::Test, + // ) +} diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 64dbcfd4a..66dedad4f 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -18,6 +18,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +mod benchmarking; pub mod weights; use codec::{Codec, MaxEncodedLen}; @@ -138,8 +139,8 @@ pub mod pallet { /// Remove `accounts` from the barrier's RemainingXcmLimit storage #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::remove_accounts_to_native_barrier())] - pub fn remove_accounts_to_native_barrier( + #[pallet::weight(T::WeightInfo::remove_accounts_from_native_barrier())] + pub fn remove_accounts_from_native_barrier( origin: OriginFor, accounts: Vec, ) -> DispatchResultWithPostInfo { @@ -173,6 +174,7 @@ pub mod pallet { /// Stores daily limit value #[pallet::storage] + #[pallet::getter(fn get_daily_xcm_limit)] pub type DailyXcmLimit = StorageValue<_, T::Balance, OptionQuery>; /// Stores remaining limit for each account. Skipped days are accumulated. @@ -186,6 +188,7 @@ pub mod pallet { /// Stores starting unix time for the native barrier logic #[pallet::storage] + #[pallet::getter(fn get_start_unix_time)] pub type StartUnixTime = StorageValue<_, Duration, OptionQuery>; #[pallet::genesis_config] diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index b93da5fa0..f9a3844be 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -57,7 +57,7 @@ pub trait WeightInfo { fn add_accounts_to_native_barrier() -> Weight; - fn remove_accounts_to_native_barrier() -> Weight; + fn remove_accounts_from_native_barrier() -> Weight; } /// Weights for pallet_balances using the Substrate node and recommended hardware. @@ -94,7 +94,7 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn remove_accounts_to_native_barrier() -> Weight { + fn remove_accounts_from_native_barrier() -> Weight { // Minimum execution time: 31_225 nanoseconds. Weight::from_ref_time(31_946_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) @@ -132,7 +132,7 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: System Account (r:1 w:1) - fn remove_accounts_to_native_barrier() -> Weight { + fn remove_accounts_from_native_barrier() -> Weight { // Minimum execution time: 31_225 nanoseconds. Weight::from_ref_time(31_946_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) From ba1fc949025ab89a4369339150cb914a627ffa98 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 17 Aug 2023 11:43:51 +0300 Subject: [PATCH 31/69] Add benchamrk unit tests and add to runtimes Signed-off-by: Georgi Zlatarev --- Cargo.lock | 71 +++++----- pallets/native-barrier/Cargo.toml | 7 + pallets/native-barrier/src/benchmarking.rs | 16 ++- pallets/native-barrier/src/lib.rs | 1 + pallets/native-barrier/src/mock.rs | 146 +++++++++++++++++++++ runtime/calamari/Cargo.toml | 2 + runtime/calamari/src/lib.rs | 3 +- runtime/manta/Cargo.toml | 1 + runtime/manta/src/lib.rs | 3 +- 9 files changed, 209 insertions(+), 41 deletions(-) create mode 100644 pallets/native-barrier/src/mock.rs diff --git a/Cargo.lock b/Cargo.lock index 0e6d9f3ec..66f8d9a7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,7 +1129,7 @@ dependencies = [ "pallet-aura-style-filter", "pallet-author-inherent", "pallet-authorship", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-collective", "pallet-conviction-voting", "pallet-democracy", @@ -1206,7 +1206,7 @@ dependencies = [ "frame-system", "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-timestamp", "parity-scale-codec", "scale-info", @@ -4195,7 +4195,7 @@ dependencies = [ "orml-xtokens", "pallet-asset-manager", "pallet-assets", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-collective", "pallet-democracy", "pallet-manta-pay", @@ -4500,7 +4500,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-bounties", "pallet-child-bounties", "pallet-collective", @@ -5419,7 +5419,7 @@ dependencies = [ "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-aura", "pallet-authorship", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-session", "pallet-timestamp", "parity-scale-codec", @@ -5548,7 +5548,7 @@ dependencies = [ "pallet-aura-style-filter", "pallet-author-inherent", "pallet-authorship", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-collective", "pallet-democracy", "pallet-farming", @@ -6539,7 +6539,7 @@ dependencies = [ "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-assets", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", "sp-arithmetic", @@ -6682,7 +6682,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "sp-core", @@ -6695,33 +6695,33 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-native-barrier", - "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", "sp-runtime", "sp-std", ] [[package]] name = "pallet-balances" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +version = "4.4.0" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "pallet-native-barrier", + "pallet-transaction-payment", "parity-scale-codec", "scale-info", + "sp-core", + "sp-io", "sp-runtime", "sp-std", ] @@ -6921,7 +6921,7 @@ dependencies = [ "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", "sp-arithmetic", @@ -7067,7 +7067,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-parachain-staking", "pallet-preimage", "pallet-randomness", @@ -7109,7 +7109,7 @@ dependencies = [ "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-manta-support", "pallet-native-barrier", "pallet-tx-pause", @@ -7147,7 +7147,7 @@ dependencies = [ "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-manta-pay", "pallet-manta-support", "pallet-timestamp", @@ -7250,7 +7250,7 @@ dependencies = [ "frame-system", "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-manta-support", "parity-scale-codec", "safe-regex", @@ -7268,9 +7268,14 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "pallet-balances 4.4.0", + "pallet-timestamp", "parity-scale-codec", "scale-info", + "sp-core", + "sp-io", "sp-runtime", "sp-std", ] @@ -7346,7 +7351,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "serde", @@ -7365,7 +7370,7 @@ dependencies = [ "frame-support", "frame-system", "pallet-babe", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-grandpa", "pallet-im-online", "pallet-offences", @@ -7389,7 +7394,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-session", "parity-scale-codec", "scale-info", @@ -7449,7 +7454,7 @@ dependencies = [ "manta-primitives", "nimbus-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", "serde", @@ -7744,7 +7749,7 @@ dependencies = [ "frame-support", "frame-system", "impl-trait-for-tuples", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "serde", @@ -7761,7 +7766,7 @@ dependencies = [ "frame-system", "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", "sp-core", @@ -8958,7 +8963,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-bounties", "pallet-child-bounties", "pallet-collective", @@ -9043,7 +9048,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-beefy-mmr", "pallet-election-provider-multi-phase", "pallet-session", @@ -9116,7 +9121,7 @@ dependencies = [ "pallet-authority-discovery", "pallet-authorship", "pallet-babe", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-session", "pallet-staking", "pallet-timestamp", @@ -9982,7 +9987,7 @@ dependencies = [ "pallet-authority-discovery", "pallet-authorship", "pallet-babe", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", @@ -10143,7 +10148,7 @@ dependencies = [ "orml-xtokens", "pallet-asset-manager", "pallet-assets", - "pallet-balances 4.0.0-dev", + "pallet-balances 4.4.0", "pallet-transaction-payment", "pallet-utility", "pallet-xcm", @@ -14509,7 +14514,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-bags-list", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "pallet-collective", "pallet-democracy", "pallet-election-provider-multi-phase", @@ -15102,7 +15107,7 @@ dependencies = [ "frame-system", "log", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", - "pallet-balances 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37)", + "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", "serde", diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index c0cbcb773..27398f725 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -21,6 +21,13 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +[dev-dependencies] +pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { path = "../balances" } +manta-primitives = { path = "../../primitives/manta" } + [features] default = ["std"] runtime-benchmarks = [ diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 435d5fd32..91baac1bd 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -55,6 +55,8 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit)); + let start_unix_time = Duration::default(); + NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time)); let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -75,6 +77,8 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit)); + let start_unix_time = Duration::default(); + NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time)); let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -87,7 +91,7 @@ benchmarks! { barrier_addresses[2].clone(), barrier_addresses[4].clone() ]; - NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses); + let _ = NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses)?; }: remove_accounts_from_native_barrier(RawOrigin::Root, remove_addresses) verify { assert_eq!(None, RemainingXcmLimit::::get(account::("address_0", 0, SEED))); @@ -95,9 +99,9 @@ benchmarks! { assert_eq!(None, RemainingXcmLimit::::get(account::("address_4", 0, SEED))); } - // impl_benchmark_test_suite!( - // NativeBarrier, - // crate::tests_composite::ExtBuilder::default().build(), - // crate::tests_composite::Test, - // ) + impl_benchmark_test_suite!( + NativeBarrier, + crate::mock::ExtBuilder::default().build(), + crate::mock::Runtime, + ); } diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 66dedad4f..bf077db4c 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -19,6 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] mod benchmarking; +mod mock; pub mod weights; use codec::{Codec, MaxEncodedLen}; diff --git a/pallets/native-barrier/src/mock.rs b/pallets/native-barrier/src/mock.rs new file mode 100644 index 000000000..96ccd709f --- /dev/null +++ b/pallets/native-barrier/src/mock.rs @@ -0,0 +1,146 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . +// +// The pallet-tx-pause pallet is forked from Acala's transaction-pause module https://github.com/AcalaNetwork/Acala/tree/master/modules/transaction-pause +// The original license is the following - SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +//! Mocks for the native barrier pallet. + +#![cfg(test)] + +use super::*; +use frame_support::{ + construct_runtime, ord_parameter_types, parameter_types, + traits::{ConstU32, ConstU64, Contains, IsInVec}, +}; +use frame_system::EnsureRoot; +use manta_primitives::types::{Balance, BlockNumber, Header}; + +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; + +pub type AccountId = u128; + +mod pallet_native_barrier { + pub use super::super::*; +} + +pub struct BaseFilter; +impl Contains for BaseFilter { + fn contains(call: &RuntimeCall) -> bool { + true + } +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = BlockNumber; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU32<250>; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = BaseFilter; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const NativeTokenExistentialDeposit: Balance = 10; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = NativeTokenExistentialDeposit; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = ConstU32<50>; + type ReserveIdentifier = (); + type WeightInfo = (); + type NativeBarrierType = NativeBarrier; +} + +ord_parameter_types! { + pub const One: AccountId = 1; +} + +parameter_types! { + pub NonPausablePallets: Vec> = vec![b"Democracy".to_vec(), b"Balances".to_vec(), b"Council".to_vec(), b"CouncilCollective".to_vec(), b"TechnicalCommittee".to_vec(), b"TechnicalCollective".to_vec()]; +} + +impl Config for Runtime { + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type UnixTime = Timestamp; + type WeightInfo = (); +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = ConstU64<5>; + type WeightInfo = (); +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + NativeBarrier: pallet_native_barrier::{Pallet, Storage, Call, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Balances: pallet_balances::{Pallet, Storage, Call, Event}, + } +); + +pub struct ExtBuilder; + +impl Default for ExtBuilder { + fn default() -> Self { + ExtBuilder + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + t.into() + } +} diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 628f3a76e..90cbf6c78 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -183,6 +183,8 @@ runtime-benchmarks = [ "pallet-conviction-voting/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", "pallet-ranked-collective/runtime-benchmarks", + 'pallet-native-barrier/runtime-benchmarks', + ] try-runtime = [ 'frame-try-runtime', diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index ecdd6ebb0..78508bb86 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -1047,7 +1047,7 @@ extern crate frame_benchmarking; mod benches { frame_benchmarking::define_benchmarks!( // Substrate pallets - // [pallet_balances, Balances] + [pallet_balances, Balances] [pallet_multisig, Multisig] [frame_system, SystemBench::] [pallet_timestamp, Timestamp] @@ -1071,6 +1071,7 @@ mod benches { [pallet_manta_pay, MantaPay] [pallet_manta_sbt, MantaSbt] [pallet_name_service, NameService] + [pallet_native_barrier, NativeBarrier] // Dex [zenlink_protocol, ZenlinkProtocol] [pallet_farming, Farming] diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index 3825566ff..21b9cdc59 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -164,6 +164,7 @@ runtime-benchmarks = [ 'pallet-name-service/runtime-benchmarks', "zenlink-protocol/runtime-benchmarks", 'pallet-farming/runtime-benchmarks', + 'pallet-native-barrier/runtime-benchmarks', ] try-runtime = [ 'frame-try-runtime', diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 443a4e39c..86e821f31 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -1014,7 +1014,7 @@ extern crate frame_benchmarking; mod benches { frame_benchmarking::define_benchmarks!( // Substrate pallets - // [pallet_balances, Balances] + [pallet_balances, Balances] [pallet_democracy, Democracy] [pallet_collective, Council] [pallet_membership, CouncilMembership] @@ -1043,6 +1043,7 @@ mod benches { [pallet_name_service, NameService] [zenlink_protocol, ZenlinkProtocol] [pallet_farming, Farming] + [pallet_native_barrier, NativeBarrier] // Nimbus pallets [pallet_author_inherent, AuthorInherent] ); From 9745b792fe0783e3ac4b2182ec6e30a2458c72df Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 17 Aug 2023 12:23:40 +0300 Subject: [PATCH 32/69] Add on_initialize benchmark and generate weight file in pallet Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/Cargo.toml | 3 +- pallets/native-barrier/README.md | 122 ---------------- pallets/native-barrier/src/benchmarking.rs | 32 +++-- pallets/native-barrier/src/mock.rs | 16 ++- pallets/native-barrier/src/weights.rs | 153 ++++++++++----------- 5 files changed, 111 insertions(+), 215 deletions(-) delete mode 100644 pallets/native-barrier/README.md diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 27398f725..3c89e519c 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -20,13 +20,13 @@ sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-feat sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +manta-primitives = { path = '../../primitives/manta', default-features = false } [dev-dependencies] pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } -manta-primitives = { path = "../../primitives/manta" } [features] default = ["std"] @@ -42,5 +42,6 @@ std = [ "sp-runtime/std", "sp-std/std", "orml-traits/std", + "manta-primitives/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/native-barrier/README.md b/pallets/native-barrier/README.md deleted file mode 100644 index 93e424a89..000000000 --- a/pallets/native-barrier/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Balances Module - -The Balances module provides functionality for handling accounts and balances. - -- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) -- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) -- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) - -## Overview - -The Balances module provides functions for: - -- Getting and setting free balances. -- Retrieving total, reserved and unreserved balances. -- Repatriating a reserved balance to a beneficiary account that exists. -- Transferring a balance between accounts (when not reserved). -- Slashing an account balance. -- Account creation and removal. -- Managing total issuance. -- Setting and managing locks. - -### Terminology - -- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents -"dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) - fall below this, then the account is said to be dead; and it loses its functionality as well as any - prior history and all information on it is removed from the chain's state. - No account should ever have a total balance that is strictly between 0 and the existential - deposit (exclusive). If this ever happens, it indicates either a bug in this module or an - erroneous raw mutation of storage. - -- **Total Issuance:** The total number of units in existence in a system. - -- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its -total balance has become zero (or, strictly speaking, less than the Existential Deposit). - -- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only - balance that matters for most operations. - -- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. - Reserved balance can still be slashed, but only after all the free balance has been slashed. - -- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting -(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will -return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is -simply dropped, it should automatically maintain any book-keeping such as total issuance.) - -- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple -locks always operate over the same funds, so they "overlay" rather than "stack". - -### Implementations - -The Balances module provides implementations for the following traits. If these traits provide the functionality -that you need, then you can avoid coupling with the Balances module. - -- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing with a -fungible assets system. -- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): -Functions for dealing with assets that can be reserved from an account. -- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions for -dealing with accounts that allow liquidity restrictions. -- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling -imbalances between total issuance in the system and account balances. Must be used when a function -creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). -- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to say whether a -given account is unused. - -## Interface - -### Dispatchable Functions - -- `transfer` - Transfer some liquid free balance to another account. -- `set_balance` - Set the balances of a given account. The origin of this call must be root. - -## Usage - -The following examples show how to use the Balances module in your custom module. - -### Examples from the FRAME - -The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: - -```rust -use frame_support::traits::Currency; - -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; - -``` - -The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: - -```rust -use frame_support::traits::{WithdrawReasons, LockableCurrency}; -use sp_runtime::traits::Bounded; -pub trait Config: frame_system::Config { - type Currency: LockableCurrency; -} - -fn update_ledger( - controller: &T::AccountId, - ledger: &StakingLedger -) { - T::Currency::set_lock( - STAKING_ID, - &ledger.stash, - ledger.total, - WithdrawReasons::all() - ); - // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. -} -``` - -## Genesis config - -The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). - -## Assumptions - -* Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. - -License: Apache-2.0 diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 91baac1bd..1fd76dcc0 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -23,15 +23,29 @@ use super::*; use crate::Pallet as NativeBarrier; use core::time::Duration; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; -use frame_support::traits::UnixTime; +use frame_support::traits::Hooks; use frame_system::RawOrigin; -use sp_runtime::traits::{Bounded, Zero}; +use sp_runtime::traits::Zero; const SEED: u32 = 0; -// existential deposit multiplier -const ED_MULTIPLIER: u32 = 10; benchmarks! { + //TODO: docs + on_initialize { + let daily_limit = T::Balance::zero(); + let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; + let start_unix_time = Duration::default(); + let _ = NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time))?; + let barrier_addresses: Vec = vec![ + account("address_0", 0, SEED), + account("address_1", 0, SEED), + account("address_2", 0, SEED), + account("address_3", 0, SEED), + account("address_4", 0, SEED) + ]; + let _ = NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses)?; + }:{NativeBarrier::::on_initialize(T::BlockNumber::from(1_000_000u32));} + // set_start_unix_time { let caller: T::AccountId = whitelisted_caller(); @@ -54,9 +68,9 @@ benchmarks! { add_accounts_to_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); - NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit)); + let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; let start_unix_time = Duration::default(); - NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time)); + let _ = NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time)); let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -76,9 +90,9 @@ benchmarks! { remove_accounts_from_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); - NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit)); + let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; let start_unix_time = Duration::default(); - NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time)); + let _ = NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time))?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -86,12 +100,12 @@ benchmarks! { account("address_3", 0, SEED), account("address_4", 0, SEED) ]; + let _ = NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses.clone())?; let remove_addresses = vec![ barrier_addresses[0].clone(), barrier_addresses[2].clone(), barrier_addresses[4].clone() ]; - let _ = NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses)?; }: remove_accounts_from_native_barrier(RawOrigin::Root, remove_addresses) verify { assert_eq!(None, RemainingXcmLimit::::get(account::("address_0", 0, SEED))); diff --git a/pallets/native-barrier/src/mock.rs b/pallets/native-barrier/src/mock.rs index 96ccd709f..1f9dc5c73 100644 --- a/pallets/native-barrier/src/mock.rs +++ b/pallets/native-barrier/src/mock.rs @@ -24,10 +24,12 @@ use super::*; use frame_support::{ construct_runtime, ord_parameter_types, parameter_types, - traits::{ConstU32, ConstU64, Contains, IsInVec}, + traits::{ConstU32, Contains}, +}; +use manta_primitives::{ + constants::time::SLOT_DURATION, + types::{Balance, BlockNumber, Header}, }; -use frame_system::EnsureRoot; -use manta_primitives::types::{Balance, BlockNumber, Header}; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; @@ -40,7 +42,7 @@ mod pallet_native_barrier { pub struct BaseFilter; impl Contains for BaseFilter { - fn contains(call: &RuntimeCall) -> bool { + fn contains(_call: &RuntimeCall) -> bool { true } } @@ -104,10 +106,14 @@ impl Config for Runtime { type WeightInfo = (); } +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} + impl pallet_timestamp::Config for Runtime { type Moment = u64; type OnTimestampSet = (); - type MinimumPeriod = ConstU64<5>; + type MinimumPeriod = MinimumPeriod; type WeightInfo = (); } diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index f9a3844be..51157c789 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -13,130 +13,127 @@ // // You should have received a copy of the GNU General Public License // along with Manta. If not, see . -// -//! # Native Barrier Pallet -//! Autogenerated weights for pallet_balances +//! Autogenerated weights for pallet_native_barrier //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-11-07, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! HOSTNAME: `bm2`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! DATE: 2023-08-17, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("manta-dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate +// ./target/release/manta // benchmark // pallet -// --chain=dev +// --chain=manta-dev // --steps=50 -// --repeat=20 -// --pallet=pallet_balances +// --repeat=40 +// --pallet=pallet_native_barrier // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/balances/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./scripts/benchmarking/frame-weights-output/pallet_native_barrier.rs +// --template=.github/resources/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; -/// Weight functions needed for pallet_balances. +/// Weight functions needed for pallet_native_barrier. pub trait WeightInfo { - - fn on_initialize() -> Weight; - - fn set_start_unix_time() -> Weight; - - fn set_daily_xcm_limit() -> Weight; - - fn add_accounts_to_native_barrier() -> Weight; - - fn remove_accounts_from_native_barrier() -> Weight; + fn on_initialize() -> Weight; + fn set_start_unix_time() -> Weight; + fn set_daily_xcm_limit() -> Weight; + fn add_accounts_to_native_barrier() -> Weight; + fn remove_accounts_from_native_barrier() -> Weight; } -/// Weights for pallet_balances using the Substrate node and recommended hardware. +/// Weights for pallet_native_barrier using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - - // Storage: Farming PoolInfos (r:1 w:0) - // Storage: Farming GaugePoolInfos (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + // Storage: NativeBarrier LastDayProcessed (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 5_170 nanoseconds. - Weight::from_ref_time(5_433_000) - .saturating_add(T::DbWeight::get().reads(2)) + // Minimum execution time: 45_706 nanoseconds. + Weight::from_ref_time(46_457_000) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(6)) } - - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier StartUnixTime (r:0 w:1) fn set_start_unix_time() -> Weight { - // Minimum execution time: 48_134 nanoseconds. - Weight::from_ref_time(48_811_000 as u64) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + // Minimum execution time: 14_287 nanoseconds. + Weight::from_ref_time(14_948_000) + .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 36_586 nanoseconds. - Weight::from_ref_time(36_966_000 as u64) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + // Minimum execution time: 14_017 nanoseconds. + Weight::from_ref_time(14_628_000) + .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_486 nanoseconds. - Weight::from_ref_time(28_940_000 as u64) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + // Minimum execution time: 28_283 nanoseconds. + Weight::from_ref_time(28_994_000) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) } - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 31_225 nanoseconds. - Weight::from_ref_time(31_946_000 as u64) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + // Minimum execution time: 16_831 nanoseconds. + Weight::from_ref_time(17_824_000) + .saturating_add(T::DbWeight::get().writes(3)) } - } // For backwards compatibility and tests impl WeightInfo for () { + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + // Storage: NativeBarrier LastDayProcessed (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - Weight::from_ref_time(5_433_000) - .saturating_add(RocksDbWeight::get().reads(2)) + // Minimum execution time: 45_706 nanoseconds. + Weight::from_ref_time(46_457_000) + .saturating_add(RocksDbWeight::get().reads(10)) + .saturating_add(RocksDbWeight::get().writes(6)) } - - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier StartUnixTime (r:0 w:1) fn set_start_unix_time() -> Weight { - // Minimum execution time: 48_134 nanoseconds. - Weight::from_ref_time(48_811_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + // Minimum execution time: 14_287 nanoseconds. + Weight::from_ref_time(14_948_000) + .saturating_add(RocksDbWeight::get().writes(1)) } - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 36_586 nanoseconds. - Weight::from_ref_time(36_966_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + // Minimum execution time: 14_017 nanoseconds. + Weight::from_ref_time(14_628_000) + .saturating_add(RocksDbWeight::get().writes(1)) } - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_486 nanoseconds. - Weight::from_ref_time(28_940_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + // Minimum execution time: 28_283 nanoseconds. + Weight::from_ref_time(28_994_000) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(5)) } - // Storage: System Account (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 31_225 nanoseconds. - Weight::from_ref_time(31_946_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + // Minimum execution time: 16_831 nanoseconds. + Weight::from_ref_time(17_824_000) + .saturating_add(RocksDbWeight::get().writes(3)) } - } From 2e0760b92e73ad1006eaa2f7124a14c8bf5cccb7 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 17 Aug 2023 12:32:23 +0300 Subject: [PATCH 33/69] Add weights file to runtiems Signed-off-by: Georgi Zlatarev --- runtime/calamari/src/lib.rs | 2 +- runtime/calamari/src/weights/mod.rs | 1 + .../src/weights/pallet_native_barrier.rs | 139 ++++++++++++++++++ runtime/manta/src/lib.rs | 2 +- runtime/manta/src/weights/mod.rs | 1 + .../src/weights/pallet_native_barrier.rs | 139 ++++++++++++++++++ 6 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 runtime/calamari/src/weights/pallet_native_barrier.rs create mode 100644 runtime/manta/src/weights/pallet_native_barrier.rs diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index 78508bb86..e5c59d25a 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -465,7 +465,7 @@ impl pallet_native_barrier::Config for Runtime { type Balance = Balance; type RuntimeEvent = RuntimeEvent; type UnixTime = Timestamp; - type WeightInfo = (); + type WeightInfo = weights::pallet_native_barrier::SubstrateWeight; } parameter_types! { diff --git a/runtime/calamari/src/weights/mod.rs b/runtime/calamari/src/weights/mod.rs index 0bdf918f6..11f19c0cf 100644 --- a/runtime/calamari/src/weights/mod.rs +++ b/runtime/calamari/src/weights/mod.rs @@ -33,6 +33,7 @@ pub mod pallet_manta_sbt; pub mod pallet_membership; pub mod pallet_multisig; pub mod pallet_name_service; +pub mod pallet_native_barrier; pub mod pallet_parachain_staking; pub mod pallet_preimage; pub mod pallet_randomness; diff --git a/runtime/calamari/src/weights/pallet_native_barrier.rs b/runtime/calamari/src/weights/pallet_native_barrier.rs new file mode 100644 index 000000000..e583cd8ff --- /dev/null +++ b/runtime/calamari/src/weights/pallet_native_barrier.rs @@ -0,0 +1,139 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for pallet_native_barrier +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-17, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("manta-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/manta +// benchmark +// pallet +// --chain=manta-dev +// --steps=50 +// --repeat=40 +// --pallet=pallet_native_barrier +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./scripts/benchmarking/frame-weights-output/pallet_native_barrier.rs +// --template=.github/resources/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for pallet_native_barrier. +pub trait WeightInfo { + fn on_initialize() -> Weight; + fn set_start_unix_time() -> Weight; + fn set_daily_xcm_limit() -> Weight; + fn add_accounts_to_native_barrier() -> Weight; + fn remove_accounts_from_native_barrier() -> Weight; +} + +/// Weights for pallet_native_barrier using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl pallet_native_barrier::WeightInfo for SubstrateWeight { + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + // Storage: NativeBarrier LastDayProcessed (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) + fn on_initialize() -> Weight { + // Minimum execution time: 45_706 nanoseconds. + Weight::from_ref_time(46_457_000) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: NativeBarrier StartUnixTime (r:0 w:1) + fn set_start_unix_time() -> Weight { + // Minimum execution time: 14_287 nanoseconds. + Weight::from_ref_time(14_948_000) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) + fn set_daily_xcm_limit() -> Weight { + // Minimum execution time: 14_017 nanoseconds. + Weight::from_ref_time(14_628_000) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) + fn add_accounts_to_native_barrier() -> Weight { + // Minimum execution time: 28_283 nanoseconds. + Weight::from_ref_time(28_994_000) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + fn remove_accounts_from_native_barrier() -> Weight { + // Minimum execution time: 16_831 nanoseconds. + Weight::from_ref_time(17_824_000) + .saturating_add(T::DbWeight::get().writes(3)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + // Storage: NativeBarrier LastDayProcessed (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) + fn on_initialize() -> Weight { + // Minimum execution time: 45_706 nanoseconds. + Weight::from_ref_time(46_457_000) + .saturating_add(RocksDbWeight::get().reads(10)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: NativeBarrier StartUnixTime (r:0 w:1) + fn set_start_unix_time() -> Weight { + // Minimum execution time: 14_287 nanoseconds. + Weight::from_ref_time(14_948_000) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) + fn set_daily_xcm_limit() -> Weight { + // Minimum execution time: 14_017 nanoseconds. + Weight::from_ref_time(14_628_000) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) + fn add_accounts_to_native_barrier() -> Weight { + // Minimum execution time: 28_283 nanoseconds. + Weight::from_ref_time(28_994_000) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + fn remove_accounts_from_native_barrier() -> Weight { + // Minimum execution time: 16_831 nanoseconds. + Weight::from_ref_time(17_824_000) + .saturating_add(RocksDbWeight::get().writes(3)) + } +} diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 86e821f31..fe05f3c05 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -454,7 +454,7 @@ impl pallet_native_barrier::Config for Runtime { type Balance = Balance; type RuntimeEvent = RuntimeEvent; type UnixTime = Timestamp; - type WeightInfo = (); + type WeightInfo = weights::pallet_native_barrier::SubstrateWeight; } parameter_types! { diff --git a/runtime/manta/src/weights/mod.rs b/runtime/manta/src/weights/mod.rs index 366ae36a2..62d734066 100644 --- a/runtime/manta/src/weights/mod.rs +++ b/runtime/manta/src/weights/mod.rs @@ -32,6 +32,7 @@ pub mod pallet_manta_sbt; pub mod pallet_membership; pub mod pallet_multisig; pub mod pallet_name_service; +pub mod pallet_native_barrier; pub mod pallet_parachain_staking; pub mod pallet_preimage; pub mod pallet_randomness; diff --git a/runtime/manta/src/weights/pallet_native_barrier.rs b/runtime/manta/src/weights/pallet_native_barrier.rs new file mode 100644 index 000000000..e583cd8ff --- /dev/null +++ b/runtime/manta/src/weights/pallet_native_barrier.rs @@ -0,0 +1,139 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for pallet_native_barrier +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-17, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("manta-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/manta +// benchmark +// pallet +// --chain=manta-dev +// --steps=50 +// --repeat=40 +// --pallet=pallet_native_barrier +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./scripts/benchmarking/frame-weights-output/pallet_native_barrier.rs +// --template=.github/resources/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for pallet_native_barrier. +pub trait WeightInfo { + fn on_initialize() -> Weight; + fn set_start_unix_time() -> Weight; + fn set_daily_xcm_limit() -> Weight; + fn add_accounts_to_native_barrier() -> Weight; + fn remove_accounts_from_native_barrier() -> Weight; +} + +/// Weights for pallet_native_barrier using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl pallet_native_barrier::WeightInfo for SubstrateWeight { + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + // Storage: NativeBarrier LastDayProcessed (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) + fn on_initialize() -> Weight { + // Minimum execution time: 45_706 nanoseconds. + Weight::from_ref_time(46_457_000) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: NativeBarrier StartUnixTime (r:0 w:1) + fn set_start_unix_time() -> Weight { + // Minimum execution time: 14_287 nanoseconds. + Weight::from_ref_time(14_948_000) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) + fn set_daily_xcm_limit() -> Weight { + // Minimum execution time: 14_017 nanoseconds. + Weight::from_ref_time(14_628_000) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) + fn add_accounts_to_native_barrier() -> Weight { + // Minimum execution time: 28_283 nanoseconds. + Weight::from_ref_time(28_994_000) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + fn remove_accounts_from_native_barrier() -> Weight { + // Minimum execution time: 16_831 nanoseconds. + Weight::from_ref_time(17_824_000) + .saturating_add(T::DbWeight::get().writes(3)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + // Storage: NativeBarrier LastDayProcessed (r:1 w:1) + // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) + fn on_initialize() -> Weight { + // Minimum execution time: 45_706 nanoseconds. + Weight::from_ref_time(46_457_000) + .saturating_add(RocksDbWeight::get().reads(10)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: NativeBarrier StartUnixTime (r:0 w:1) + fn set_start_unix_time() -> Weight { + // Minimum execution time: 14_287 nanoseconds. + Weight::from_ref_time(14_948_000) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) + fn set_daily_xcm_limit() -> Weight { + // Minimum execution time: 14_017 nanoseconds. + Weight::from_ref_time(14_628_000) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) + fn add_accounts_to_native_barrier() -> Weight { + // Minimum execution time: 28_283 nanoseconds. + Weight::from_ref_time(28_994_000) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + fn remove_accounts_from_native_barrier() -> Weight { + // Minimum execution time: 16_831 nanoseconds. + Weight::from_ref_time(17_824_000) + .saturating_add(RocksDbWeight::get().writes(3)) + } +} From 24a19b4a55663bbcf05e6950bbd01cb3cd786a7b Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 17 Aug 2023 15:42:48 +0300 Subject: [PATCH 34/69] First tests Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 3 ++ pallets/native-barrier/src/tests.rs | 84 +++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 pallets/native-barrier/src/tests.rs diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index bf077db4c..31dd22312 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -20,6 +20,8 @@ mod benchmarking; mod mock; +#[cfg(test)] +mod tests; pub mod weights; use codec::{Codec, MaxEncodedLen}; @@ -180,6 +182,7 @@ pub mod pallet { /// Stores remaining limit for each account. Skipped days are accumulated. #[pallet::storage] + #[pallet::getter(fn get_remaining_xcm_limit)] pub type RemainingXcmLimit = StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs new file mode 100644 index 000000000..5efacb413 --- /dev/null +++ b/pallets/native-barrier/src/tests.rs @@ -0,0 +1,84 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +use crate::{ + mock::{AccountId, ExtBuilder, NativeBarrier, Runtime, RuntimeOrigin}, + Config, Error, +}; +use manta_primitives::types::Balance; + +use core::time::Duration; +use frame_support::{assert_err, assert_noop, assert_ok, traits::Currency}; +use frame_system::RawOrigin; + +#[test] +fn extrinsics_as_normal_user_should_not_work() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + NativeBarrier::set_daily_xcm_limit(RuntimeOrigin::signed(1), Some(10u128)), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + NativeBarrier::set_start_unix_time(RuntimeOrigin::signed(1), Some(Duration::default())), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + NativeBarrier::add_accounts_to_native_barrier(RuntimeOrigin::signed(1), vec![]), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + NativeBarrier::remove_accounts_from_native_barrier(RuntimeOrigin::signed(1), vec![]), + sp_runtime::DispatchError::BadOrigin + ); + }); +} + +#[test] +fn extrinsics_as_root_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_err!( + NativeBarrier::add_accounts_to_native_barrier(RawOrigin::Root.into(), vec![]), + Error::::XcmDailyLimitNotSet + ); + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + Some(10u128) + )); + assert_err!( + NativeBarrier::add_accounts_to_native_barrier(RawOrigin::Root.into(), vec![]), + Error::::StartUnixTimeNotSet + ); + assert_ok!(NativeBarrier::set_start_unix_time( + RawOrigin::Root.into(), + Some(Duration::default()) + )); + assert_ok!(NativeBarrier::add_accounts_to_native_barrier( + RawOrigin::Root.into(), + vec![1, 2, 3] + )); + assert_ne!(NativeBarrier::get_remaining_xcm_limit(1), None); + assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( + RawOrigin::Root.into(), + vec![1] + )); + assert_eq!(NativeBarrier::get_remaining_xcm_limit(1), None); + }); +} + +// TODO: +// set start in the past and checks +// set start in the future and checks +// checks should be for balances, xtokens and mantapay From 548d679e77d5b6963732e88f276f63e3cbfe036a Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 07:22:25 +0300 Subject: [PATCH 35/69] tests work Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/mock.rs | 22 +++- pallets/native-barrier/src/tests.rs | 183 +++++++++++++++++++++++++++- 2 files changed, 196 insertions(+), 9 deletions(-) diff --git a/pallets/native-barrier/src/mock.rs b/pallets/native-barrier/src/mock.rs index 1f9dc5c73..8a5cd1ed2 100644 --- a/pallets/native-barrier/src/mock.rs +++ b/pallets/native-barrier/src/mock.rs @@ -23,8 +23,10 @@ use super::*; use frame_support::{ - construct_runtime, ord_parameter_types, parameter_types, - traits::{ConstU32, Contains}, + construct_runtime, ensure, ord_parameter_types, + pallet_prelude::DispatchResult, + parameter_types, + traits::{ConstU32, Contains, UnixTime}, }; use manta_primitives::{ constants::time::SLOT_DURATION, @@ -95,6 +97,20 @@ ord_parameter_types! { pub const One: AccountId = 1; } +use std::cell::RefCell; + +// This will be our mutable mock time. +thread_local! { + pub static MOCK_TIME: RefCell = RefCell::new(Duration::default()); +} +pub struct TestTimeSource; + +impl UnixTime for TestTimeSource { + fn now() -> Duration { + MOCK_TIME.with(|time| *time.borrow()) + } +} + parameter_types! { pub NonPausablePallets: Vec> = vec![b"Democracy".to_vec(), b"Balances".to_vec(), b"Council".to_vec(), b"CouncilCollective".to_vec(), b"TechnicalCommittee".to_vec(), b"TechnicalCollective".to_vec()]; } @@ -102,7 +118,7 @@ parameter_types! { impl Config for Runtime { type Balance = Balance; type RuntimeEvent = RuntimeEvent; - type UnixTime = Timestamp; + type UnixTime = TestTimeSource; type WeightInfo = (); } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 5efacb413..63b7ab243 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -15,13 +15,16 @@ // along with Manta. If not, see . use crate::{ - mock::{AccountId, ExtBuilder, NativeBarrier, Runtime, RuntimeOrigin}, + mock::{AccountId, Balances, ExtBuilder, NativeBarrier, Runtime, RuntimeOrigin, MOCK_TIME}, Config, Error, }; use manta_primitives::types::Balance; use core::time::Duration; -use frame_support::{assert_err, assert_noop, assert_ok, traits::Currency}; +use frame_support::{ + assert_err, assert_noop, assert_ok, + traits::{Currency, GenesisBuild, OnInitialize, ReservableCurrency}, +}; use frame_system::RawOrigin; #[test] @@ -78,7 +81,175 @@ fn extrinsics_as_root_should_work() { }); } -// TODO: -// set start in the past and checks -// set start in the future and checks -// checks should be for balances, xtokens and mantapay +fn set_mock_time(new_time: Duration) { + MOCK_TIME.with(|time| { + *time.borrow_mut() = new_time; + }); +} + +fn advance_mock_time(delta: Duration) { + MOCK_TIME.with(|time| { + *time.borrow_mut() += delta; + }); +} + +#[test] +fn start_in_the_past_should_work() { + ExtBuilder::default().build().execute_with(|| { + set_mock_time(Duration::default()); + // add balances to 1,2,3 + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + Some(10u128) + )); + assert_ok!(NativeBarrier::set_start_unix_time( + RawOrigin::Root.into(), + Some(Duration::default()) + )); + + // transfer more than limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); + + assert_ok!(NativeBarrier::add_accounts_to_native_barrier( + RawOrigin::Root.into(), + vec![1, 2, 3] + )); + + // transfer under limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 5)); + // transfer more than limit should not work + assert_err!( + Balances::transfer(RuntimeOrigin::signed(1), 2, 7), + Error::::XcmTransfersLimitExceeded + ); + + // limit should be multiple of daily limit (now - epoch_start) + // roll one day + advance_mock_time(Duration::from_secs(86400)); + NativeBarrier::on_initialize(1); + + // check that limit has been updated + // transfer more than limit should not work + assert_err!( + Balances::transfer(RuntimeOrigin::signed(1), 2, 16), + Error::::XcmTransfersLimitExceeded + ); + // transfer under limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 15)); + + assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( + RawOrigin::Root.into(), + vec![1] + )); + + // transfer more than limit should work for 1 + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 3, 15)); + assert_err!( + Balances::transfer(RuntimeOrigin::signed(2), 2, 21), + Error::::XcmTransfersLimitExceeded + ); + + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + None + )); + + // transfer more than limit should work for all + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 3, 50)); + assert_ok!(Balances::transfer(RuntimeOrigin::signed(2), 3, 50)); + assert_ok!(Balances::transfer(RuntimeOrigin::signed(3), 3, 50)); + }); +} + +#[test] +fn start_in_the_future_should_work() { + ExtBuilder::default().build().execute_with(|| { + set_mock_time(Duration::default()); + // add balances to 1,2,3 + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + + // transfer more than limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); + + let daily_limit = 10u128; + let day_in_secs = 86400; + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + Some(daily_limit) + )); + assert_ok!(NativeBarrier::set_start_unix_time( + RawOrigin::Root.into(), + Some(Duration::from_secs(day_in_secs)) + )); + + assert_ok!(NativeBarrier::add_accounts_to_native_barrier( + RawOrigin::Root.into(), + vec![1, 2, 3] + )); + + // transfer more than limit should work + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 2, + daily_limit + 5 + )); + + // limit should be multiple of daily limit (now - epoch_start) + // roll one day + advance_mock_time(Duration::from_secs(day_in_secs)); + NativeBarrier::on_initialize(1); + + // check that limit has been updated + // transfer more than limit should not work + assert_err!( + Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit + 1), + Error::::XcmTransfersLimitExceeded + ); + // transfer under limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit)); + + assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( + RawOrigin::Root.into(), + vec![1] + )); + + // transfer more than limit should work for 1 + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 3, + daily_limit + 5 + )); + assert_err!( + Balances::transfer(RuntimeOrigin::signed(2), 2, daily_limit + 1), + Error::::XcmTransfersLimitExceeded + ); + + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + None + )); + + // transfer more than limit should work for all + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 3, + daily_limit * 10 + )); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(2), + 3, + daily_limit * 10 + )); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(3), + 3, + daily_limit * 10 + )); + }); +} From 6f8d87b7c303aab441a00b638007e7b544da269d Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 07:48:20 +0300 Subject: [PATCH 36/69] Clean up tests Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/tests.rs | 94 ++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 63b7ab243..343410d44 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -102,9 +102,11 @@ fn start_in_the_past_should_work() { assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + let daily_limit = 10u128; + let day_in_secs = 86400; assert_ok!(NativeBarrier::set_daily_xcm_limit( RawOrigin::Root.into(), - Some(10u128) + Some(daily_limit) )); assert_ok!(NativeBarrier::set_start_unix_time( RawOrigin::Root.into(), @@ -112,7 +114,11 @@ fn start_in_the_past_should_work() { )); // transfer more than limit should work - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 2, + daily_limit * 2 + )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -120,26 +126,38 @@ fn start_in_the_past_should_work() { )); // transfer under limit should work - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 5)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 2, + daily_limit / 2 + )); // transfer more than limit should not work assert_err!( - Balances::transfer(RuntimeOrigin::signed(1), 2, 7), + Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), Error::::XcmTransfersLimitExceeded ); // limit should be multiple of daily limit (now - epoch_start) // roll one day - advance_mock_time(Duration::from_secs(86400)); + advance_mock_time(Duration::from_secs(day_in_secs)); NativeBarrier::on_initialize(1); // check that limit has been updated // transfer more than limit should not work assert_err!( - Balances::transfer(RuntimeOrigin::signed(1), 2, 16), + Balances::transfer( + RuntimeOrigin::signed(1), + 2, + daily_limit + daily_limit / 2 + 1 + ), Error::::XcmTransfersLimitExceeded ); // transfer under limit should work - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 15)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 2, + daily_limit + daily_limit / 2 + )); assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( RawOrigin::Root.into(), @@ -147,9 +165,13 @@ fn start_in_the_past_should_work() { )); // transfer more than limit should work for 1 - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 3, 15)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 3, + daily_limit * 5 + )); assert_err!( - Balances::transfer(RuntimeOrigin::signed(2), 2, 21), + Balances::transfer(RuntimeOrigin::signed(2), 2, daily_limit * 2 + 1), Error::::XcmTransfersLimitExceeded ); @@ -159,9 +181,21 @@ fn start_in_the_past_should_work() { )); // transfer more than limit should work for all - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 3, 50)); - assert_ok!(Balances::transfer(RuntimeOrigin::signed(2), 3, 50)); - assert_ok!(Balances::transfer(RuntimeOrigin::signed(3), 3, 50)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 3, + daily_limit * 5 + )); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(2), + 3, + daily_limit * 5 + )); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(3), + 3, + daily_limit * 5 + )); }); } @@ -178,14 +212,16 @@ fn start_in_the_future_should_work() { assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); let daily_limit = 10u128; - let day_in_secs = 86400; + let future_start = 10 * 86400; + let advance_to = 20 * 86400; + let future_days = 10; assert_ok!(NativeBarrier::set_daily_xcm_limit( RawOrigin::Root.into(), Some(daily_limit) )); assert_ok!(NativeBarrier::set_start_unix_time( RawOrigin::Root.into(), - Some(Duration::from_secs(day_in_secs)) + Some(Duration::from_secs(future_start)) )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( @@ -202,17 +238,25 @@ fn start_in_the_future_should_work() { // limit should be multiple of daily limit (now - epoch_start) // roll one day - advance_mock_time(Duration::from_secs(day_in_secs)); + advance_mock_time(Duration::from_secs(advance_to)); NativeBarrier::on_initialize(1); // check that limit has been updated // transfer more than limit should not work assert_err!( - Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit + 1), + Balances::transfer( + RuntimeOrigin::signed(1), + 2, + (future_days as u128 + 1) * daily_limit + 1 + ), Error::::XcmTransfersLimitExceeded ); // transfer under limit should work - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 2, + (future_days as u128 + 1) * daily_limit + )); assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( RawOrigin::Root.into(), @@ -223,10 +267,14 @@ fn start_in_the_future_should_work() { assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 3, - daily_limit + 5 + (future_days as u128 + 1) * daily_limit + 5 )); assert_err!( - Balances::transfer(RuntimeOrigin::signed(2), 2, daily_limit + 1), + Balances::transfer( + RuntimeOrigin::signed(2), + 2, + (future_days as u128 + 1) * daily_limit + 1 + ), Error::::XcmTransfersLimitExceeded ); @@ -239,17 +287,19 @@ fn start_in_the_future_should_work() { assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 3, - daily_limit * 10 + (future_days as u128 + 1) * daily_limit * 2 )); assert_ok!(Balances::transfer( RuntimeOrigin::signed(2), 3, - daily_limit * 10 + (future_days as u128 + 1) * daily_limit * 2 )); assert_ok!(Balances::transfer( RuntimeOrigin::signed(3), 3, - daily_limit * 10 + (future_days as u128 + 1) * daily_limit * 2 )); }); } + +// todo: test that on_inits which don't roll a day will not increase limits. From b5767616f35892d97a25cf644d652966563c1342 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 08:11:34 +0300 Subject: [PATCH 37/69] clean up warnins Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/mock.rs | 4 +--- pallets/native-barrier/src/tests.rs | 10 +++------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/pallets/native-barrier/src/mock.rs b/pallets/native-barrier/src/mock.rs index 8a5cd1ed2..ff5050014 100644 --- a/pallets/native-barrier/src/mock.rs +++ b/pallets/native-barrier/src/mock.rs @@ -23,9 +23,7 @@ use super::*; use frame_support::{ - construct_runtime, ensure, ord_parameter_types, - pallet_prelude::DispatchResult, - parameter_types, + construct_runtime, ord_parameter_types, parameter_types, traits::{ConstU32, Contains, UnixTime}, }; use manta_primitives::{ diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 343410d44..e7cc481cf 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -15,16 +15,12 @@ // along with Manta. If not, see . use crate::{ - mock::{AccountId, Balances, ExtBuilder, NativeBarrier, Runtime, RuntimeOrigin, MOCK_TIME}, - Config, Error, + mock::{Balances, ExtBuilder, NativeBarrier, Runtime, RuntimeOrigin, MOCK_TIME}, + Error, }; -use manta_primitives::types::Balance; use core::time::Duration; -use frame_support::{ - assert_err, assert_noop, assert_ok, - traits::{Currency, GenesisBuild, OnInitialize, ReservableCurrency}, -}; +use frame_support::{assert_err, assert_noop, assert_ok, traits::OnInitialize}; use frame_system::RawOrigin; #[test] From c3cf14835a85cfb0fff1a7579fa69ecf562712a0 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 08:13:06 +0300 Subject: [PATCH 38/69] remove palle-tteimestamp Signed-off-by: Georgi Zlatarev --- Cargo.lock | 1 - pallets/native-barrier/Cargo.toml | 1 - pallets/native-barrier/src/mock.rs | 17 +---------------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66f8d9a7b..c4a3badd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7271,7 +7271,6 @@ dependencies = [ "manta-primitives", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", - "pallet-timestamp", "parity-scale-codec", "scale-info", "sp-core", diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 3c89e519c..30729222f 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -23,7 +23,6 @@ orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-libr manta-primitives = { path = '../../primitives/manta', default-features = false } [dev-dependencies] -pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } diff --git a/pallets/native-barrier/src/mock.rs b/pallets/native-barrier/src/mock.rs index ff5050014..10605f51b 100644 --- a/pallets/native-barrier/src/mock.rs +++ b/pallets/native-barrier/src/mock.rs @@ -26,10 +26,7 @@ use frame_support::{ construct_runtime, ord_parameter_types, parameter_types, traits::{ConstU32, Contains, UnixTime}, }; -use manta_primitives::{ - constants::time::SLOT_DURATION, - types::{Balance, BlockNumber, Header}, -}; +use manta_primitives::types::{Balance, BlockNumber, Header}; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; @@ -120,17 +117,6 @@ impl Config for Runtime { type WeightInfo = (); } -parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; -} - -impl pallet_timestamp::Config for Runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -142,7 +128,6 @@ construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, NativeBarrier: pallet_native_barrier::{Pallet, Storage, Call, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, Balances: pallet_balances::{Pallet, Storage, Call, Event}, } ); From c5c23bc06bb56a91ff27a26890eb6cc201d9069c Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 08:14:27 +0300 Subject: [PATCH 39/69] Simlify reset_remaining_xcm_limit Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 31dd22312..32b8dc14d 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -307,9 +307,7 @@ impl orml_traits::xcm_transfer::NativeBarrier Pallet { fn reset_remaining_xcm_limit(unprocessed_days: u64) { if let Some(daily_limit) = >::get() { - for (account_id, _) in RemainingXcmLimit::::iter() { - let mut remaining_limit = - >::get(&account_id).unwrap_or(daily_limit); + for (account_id, mut remaining_limit) in RemainingXcmLimit::::iter() { for _ in 0..unprocessed_days { remaining_limit += daily_limit; } From 673d5264c0cd90804491c79118e216acf1e342fa Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 08:16:17 +0300 Subject: [PATCH 40/69] storage version should be 0 Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 32b8dc14d..bcde1ad11 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -71,7 +71,7 @@ pub mod pallet { /// The current storage version. const STORAGE_VERSION: frame_support::traits::StorageVersion = - frame_support::traits::StorageVersion::new(1); + frame_support::traits::StorageVersion::new(0); #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] From e84bda887a5ea590c3838340b6ba46877c5a5a93 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 08:18:35 +0300 Subject: [PATCH 41/69] fmt' Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 30729222f..92341fdfc 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -19,13 +19,13 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive" sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } manta-primitives = { path = '../../primitives/manta', default-features = false } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] +pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -pallet-balances = { path = "../balances" } [features] default = ["std"] From b25ca884595395d8065d0c5997445975eec5198c Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 08:30:25 +0300 Subject: [PATCH 42/69] Disab le clippy for balances and fix for rest Signed-off-by: Georgi Zlatarev --- pallets/balances/src/benchmarking.rs | 1 + pallets/balances/src/lib.rs | 1 + pallets/balances/src/migration.rs | 1 + pallets/balances/src/tests.rs | 1 + pallets/balances/src/tests_composite.rs | 1 + pallets/balances/src/tests_local.rs | 1 + pallets/balances/src/tests_reentrancy.rs | 1 + pallets/native-barrier/src/lib.rs | 8 ++++---- 8 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pallets/balances/src/benchmarking.rs b/pallets/balances/src/benchmarking.rs index 60081adde..c2d538cb1 100644 --- a/pallets/balances/src/benchmarking.rs +++ b/pallets/balances/src/benchmarking.rs @@ -17,6 +17,7 @@ //! # Native Barrier Pallet benchmarking. #![cfg(feature = "runtime-benchmarks")] +#![allow(clippy::all)] use super::*; diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 05af552a3..b02f39372 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -151,6 +151,7 @@ //! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. #![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::all)] #[macro_use] mod tests; diff --git a/pallets/balances/src/migration.rs b/pallets/balances/src/migration.rs index 713f49f61..6ac29567e 100644 --- a/pallets/balances/src/migration.rs +++ b/pallets/balances/src/migration.rs @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +#![allow(clippy::all)] use super::*; use frame_support::{ diff --git a/pallets/balances/src/tests.rs b/pallets/balances/src/tests.rs index 91f9606c3..4b97404d2 100644 --- a/pallets/balances/src/tests.rs +++ b/pallets/balances/src/tests.rs @@ -17,6 +17,7 @@ //! Macro for creating the tests for the module. #![cfg(test)] +#![allow(clippy::all)] #[macro_export] macro_rules! decl_tests { diff --git a/pallets/balances/src/tests_composite.rs b/pallets/balances/src/tests_composite.rs index e8a96bfbd..0a37c8cce 100644 --- a/pallets/balances/src/tests_composite.rs +++ b/pallets/balances/src/tests_composite.rs @@ -17,6 +17,7 @@ //! Test utilities #![cfg(test)] +#![allow(clippy::all)] use crate::{self as pallet_balances, decl_tests, Config, Pallet}; use frame_support::{ diff --git a/pallets/balances/src/tests_local.rs b/pallets/balances/src/tests_local.rs index 4eb179dc5..0309738fe 100644 --- a/pallets/balances/src/tests_local.rs +++ b/pallets/balances/src/tests_local.rs @@ -17,6 +17,7 @@ //! Test utilities #![cfg(test)] +#![allow(clippy::all)] use crate::{self as pallet_balances, decl_tests, Config, Pallet}; use frame_support::{ diff --git a/pallets/balances/src/tests_reentrancy.rs b/pallets/balances/src/tests_reentrancy.rs index 53cad4d7c..35d4fbadf 100644 --- a/pallets/balances/src/tests_reentrancy.rs +++ b/pallets/balances/src/tests_reentrancy.rs @@ -17,6 +17,7 @@ //! Test setup for potential reentracy and lost updates of nested mutations. #![cfg(test)] +#![allow(clippy::all)] use crate::{self as pallet_balances, Config}; use frame_support::{ diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index bcde1ad11..49a849ded 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -122,9 +122,9 @@ pub mod pallet { ensure_root(origin)?; if let Some(daily_xcm_limit) = DailyXcmLimit::::get() { - if let Some(_) = StartUnixTime::::get() { + if StartUnixTime::::get().is_some() { for account_id in accounts.iter() { - if !RemainingXcmLimit::::contains_key(&account_id) { + if !RemainingXcmLimit::::contains_key(account_id) { RemainingXcmLimit::::insert(account_id, daily_xcm_limit); } } @@ -227,7 +227,7 @@ pub mod pallet { impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { if let Some(start_unix_time) = StartUnixTime::::get() { - if let Some(_) = DailyXcmLimit::::get() { + if DailyXcmLimit::::get().is_some() { let now = T::UnixTime::now(); if start_unix_time <= now { let days_since_start = @@ -271,7 +271,7 @@ impl orml_traits::xcm_transfer::NativeBarrier DispatchResult { - if let Some(_) = DailyXcmLimit::::get() { + if DailyXcmLimit::::get().is_some() { if let Some(start_unix_time) = >::get() { let now = T::UnixTime::now(); if start_unix_time <= now { From c35ac80b8879325d6e70b1291f44c0edbf3e4c8c Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 09:02:49 +0300 Subject: [PATCH 43/69] add comments and improve asserts in benchmark code Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/benchmarking.rs | 37 ++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 1fd76dcc0..3d5a2fbdf 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -30,7 +30,10 @@ use sp_runtime::traits::Zero; const SEED: u32 = 0; benchmarks! { - //TODO: docs + + // Worst case scenario is once per day when the RemainingXcmLimit is updated + // we set the start time as the beginning of the epoch so the on-initialize will + // add ((now - epoch_start) * daily_limit) + daily_amount for each account on_initialize { let daily_limit = T::Balance::zero(); let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; @@ -45,17 +48,26 @@ benchmarks! { ]; let _ = NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses)?; }:{NativeBarrier::::on_initialize(T::BlockNumber::from(1_000_000u32));} + verify { + let now = ::now().as_secs(); + let expected_days = now / (24 * 60 * 60); + let mut total_limit = daily_limit; + for _ in 0..expected_days { + total_limit += daily_limit; + } + for (account_id, balance) in RemainingXcmLimit::::iter() { + assert_eq!(balance, total_limit); + } + } - // + // Worst case scenario would be actually overwriting this simple storage item set_start_unix_time { let caller: T::AccountId = whitelisted_caller(); let start_unix_time = Duration::default(); }: set_start_unix_time(RawOrigin::Root, Some(start_unix_time)) - verify { - assert_eq!(NativeBarrier::::get_start_unix_time().unwrap(), start_unix_time); - } - // + + // Worst case scenario would be actually overwriting this simple storage item set_daily_xcm_limit { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); @@ -64,7 +76,8 @@ benchmarks! { assert_eq!(NativeBarrier::::get_daily_xcm_limit().unwrap(), daily_limit); } - // + // Worst case scenario would be actually writing the accounts into the barrier storage item + // Make sure the accounts have at least one daily limit once they are added add_accounts_to_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); @@ -81,12 +94,12 @@ benchmarks! { let daily_limit = T::Balance::zero(); }: add_accounts_to_native_barrier(RawOrigin::Root, barrier_addresses) verify { - for (account_id, _) in RemainingXcmLimit::::iter() { - assert_eq!(RemainingXcmLimit::::get(account_id).unwrap(), daily_limit); + for (account_id, balance) in RemainingXcmLimit::::iter() { + assert_eq!(balance, daily_limit); } } - // + // worst case scenario is to remove all the account from the barrier remove_accounts_from_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); @@ -103,13 +116,17 @@ benchmarks! { let _ = NativeBarrier::::add_accounts_to_native_barrier(RawOrigin::Root.into(), barrier_addresses.clone())?; let remove_addresses = vec![ barrier_addresses[0].clone(), + barrier_addresses[1].clone(), barrier_addresses[2].clone(), + barrier_addresses[3].clone(), barrier_addresses[4].clone() ]; }: remove_accounts_from_native_barrier(RawOrigin::Root, remove_addresses) verify { assert_eq!(None, RemainingXcmLimit::::get(account::("address_0", 0, SEED))); + assert_eq!(None, RemainingXcmLimit::::get(account::("address_1", 0, SEED))); assert_eq!(None, RemainingXcmLimit::::get(account::("address_2", 0, SEED))); + assert_eq!(None, RemainingXcmLimit::::get(account::("address_3", 0, SEED))); assert_eq!(None, RemainingXcmLimit::::get(account::("address_4", 0, SEED))); } From 22e647a7db7f5260f60646289fb459869c13eb24 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Fri, 18 Aug 2023 09:13:51 +0300 Subject: [PATCH 44/69] Use 0937 orml branch Signed-off-by: Georgi Zlatarev --- Cargo.lock | 84 +++++++++------------------ pallets/asset-manager/Cargo.toml | 2 +- pallets/balances/Cargo.toml | 2 +- pallets/collator-selection/Cargo.toml | 2 +- pallets/farming/Cargo.toml | 2 +- pallets/manta-pay/Cargo.toml | 2 +- pallets/manta-sbt/Cargo.toml | 2 +- pallets/name-service/Cargo.toml | 2 +- pallets/native-barrier/Cargo.toml | 2 +- pallets/pallet-lottery/Cargo.toml | 2 +- pallets/parachain-staking/Cargo.toml | 2 +- pallets/randomness/Cargo.toml | 2 +- pallets/tx-pause/Cargo.toml | 2 +- pallets/vesting/Cargo.toml | 2 +- primitives/manta/Cargo.toml | 2 +- runtime/calamari/Cargo.toml | 4 +- runtime/common/Cargo.toml | 4 +- runtime/integration-tests/Cargo.toml | 4 +- runtime/manta/Cargo.toml | 4 +- 19 files changed, 48 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4a3badd3..7becb5641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1121,7 +1121,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "nimbus-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -1205,7 +1205,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "pallet-timestamp", "parity-scale-codec", @@ -4191,7 +4191,7 @@ dependencies = [ "manta-primitives", "manta-runtime", "nimbus-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -5416,7 +5416,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-aura", "pallet-authorship", "pallet-balances 4.4.0", @@ -5502,7 +5502,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "parity-scale-codec", "scale-info", "smallvec", @@ -5540,7 +5540,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "nimbus-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -6400,12 +6400,12 @@ dependencies = [ [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" dependencies = [ "frame-support", "impl-trait-for-tuples", "num-traits", - "orml-utilities 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-utilities", "parity-scale-codec", "scale-info", "serde", @@ -6415,42 +6415,10 @@ dependencies = [ "xcm", ] -[[package]] -name = "orml-traits" -version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed87ba5bb12c756b3973b3f59a430bab22fc0cc9" -dependencies = [ - "frame-support", - "impl-trait-for-tuples", - "num-traits", - "orml-utilities 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", - "parity-scale-codec", - "scale-info", - "serde", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", -] - -[[package]] -name = "orml-utilities" -version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" -dependencies = [ - "frame-support", - "parity-scale-codec", - "scale-info", - "serde", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed87ba5bb12c756b3973b3f59a430bab22fc0cc9" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" dependencies = [ "frame-support", "parity-scale-codec", @@ -6464,10 +6432,10 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" dependencies = [ "frame-support", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "parity-scale-codec", "sp-runtime", "sp-std", @@ -6478,12 +6446,12 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#0ba5edb7f4d3bb0f982f1ad43db213b2f87ffa02" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" dependencies = [ "cumulus-primitives-core", "frame-support", "frame-system", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "orml-xcm-support", "pallet-xcm", "parity-scale-codec", @@ -6537,7 +6505,7 @@ dependencies = [ "frame-system", "log", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-assets", "pallet-balances 4.4.0", "parity-scale-codec", @@ -6715,7 +6683,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-native-barrier", "pallet-transaction-payment", "parity-scale-codec", @@ -6918,7 +6886,7 @@ dependencies = [ "hex-literal", "log", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.4.0", @@ -7066,7 +7034,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "pallet-parachain-staking", "pallet-preimage", @@ -7106,7 +7074,7 @@ dependencies = [ "manta-pay", "manta-primitives", "manta-util", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.4.0", @@ -7144,7 +7112,7 @@ dependencies = [ "manta-pay", "manta-primitives", "manta-util", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.4.0", @@ -7249,7 +7217,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "pallet-manta-support", "parity-scale-codec", @@ -7269,7 +7237,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", @@ -7392,7 +7360,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "pallet-session", "parity-scale-codec", @@ -7452,7 +7420,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", @@ -7764,7 +7732,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", @@ -10143,7 +10111,7 @@ dependencies = [ "frame-system", "lazy_static", "manta-primitives", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "orml-traits", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -15105,7 +15073,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", + "orml-traits", "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", diff --git a/pallets/asset-manager/Cargo.toml b/pallets/asset-manager/Cargo.toml index d99fd432e..d4b5a4c4d 100644 --- a/pallets/asset-manager/Cargo.toml +++ b/pallets/asset-manager/Cargo.toml @@ -21,7 +21,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad xcm = { git = "https://github.com/paritytech/polkadot.git", default-features = false, branch = "release-v0.9.37" } # 3rd party dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", default-features = false, branch = "polkadot-v0.9.37" } [dev-dependencies] pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index bb7d85592..411b31cba 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -21,7 +21,7 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive" sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] diff --git a/pallets/collator-selection/Cargo.toml b/pallets/collator-selection/Cargo.toml index b6778057e..98193b9a1 100644 --- a/pallets/collator-selection/Cargo.toml +++ b/pallets/collator-selection/Cargo.toml @@ -32,7 +32,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] manta-primitives = { path = "../../primitives/manta" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 9c8d19d24..5ac208f4c 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -24,7 +24,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37", default-features = false } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37", default-features = false } pallet-asset-manager = { path = "../asset-manager", default-features = false, optional = true } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "release-v0.9.37", default-features = false, optional = true } diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index 12198cba2..e3ff30315 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -122,7 +122,7 @@ manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5 manta-primitives = { path = "../../primitives/manta", default-features = false } manta-support = { package = "pallet-manta-support", path = "../manta-support", default-features = false } manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", default-features = false } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] diff --git a/pallets/manta-sbt/Cargo.toml b/pallets/manta-sbt/Cargo.toml index db2271ad0..5a0681069 100644 --- a/pallets/manta-sbt/Cargo.toml +++ b/pallets/manta-sbt/Cargo.toml @@ -127,7 +127,7 @@ manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0. lazy_static = "1.4.0" manta-crypto = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["getrandom"] } manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["groth16", "parameters", "scale", "download", "test"] } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-asset-manager = { path = "../asset-manager" } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } diff --git a/pallets/name-service/Cargo.toml b/pallets/name-service/Cargo.toml index d45eea146..fe465f73d 100644 --- a/pallets/name-service/Cargo.toml +++ b/pallets/name-service/Cargo.toml @@ -22,7 +22,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "po sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false } [dev-dependencies] -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 92341fdfc..0a221a688 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -20,7 +20,7 @@ sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-feat sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } manta-primitives = { path = '../../primitives/manta', default-features = false } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } [dev-dependencies] pallet-balances = { path = "../balances" } diff --git a/pallets/pallet-lottery/Cargo.toml b/pallets/pallet-lottery/Cargo.toml index 840cf5aa1..f1d506cee 100644 --- a/pallets/pallet-lottery/Cargo.toml +++ b/pallets/pallet-lottery/Cargo.toml @@ -40,7 +40,7 @@ rand = { version = "0.8.5", default-features = false, optional = true } calamari-runtime = { path = "../../runtime/calamari", default-features = false } lazy_static = "1.4.0" manta-collator-selection = { path = "../collator-selection", default-features = false } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-preimage = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-randomness = { path = '../randomness', default-features = false } diff --git a/pallets/parachain-staking/Cargo.toml b/pallets/parachain-staking/Cargo.toml index db6276094..7f5577181 100644 --- a/pallets/parachain-staking/Cargo.toml +++ b/pallets/parachain-staking/Cargo.toml @@ -37,7 +37,7 @@ pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/randomness/Cargo.toml b/pallets/randomness/Cargo.toml index 5c616a6bb..a2a67d92c 100644 --- a/pallets/randomness/Cargo.toml +++ b/pallets/randomness/Cargo.toml @@ -27,7 +27,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkad [dev-dependencies] derive_more = "0.99" -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances", features = ["std"] } [features] diff --git a/pallets/tx-pause/Cargo.toml b/pallets/tx-pause/Cargo.toml index a1020baa4..ade156998 100644 --- a/pallets/tx-pause/Cargo.toml +++ b/pallets/tx-pause/Cargo.toml @@ -18,7 +18,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad [dev-dependencies] manta-primitives = { path = '../../primitives/manta' } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/vesting/Cargo.toml b/pallets/vesting/Cargo.toml index 8aca47098..48eac816b 100644 --- a/pallets/vesting/Cargo.toml +++ b/pallets/vesting/Cargo.toml @@ -22,7 +22,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] chrono = "0.4" manta-primitives = { path = "../../primitives/manta" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/primitives/manta/Cargo.toml b/primitives/manta/Cargo.toml index e46add363..8b5b068ff 100644 --- a/primitives/manta/Cargo.toml +++ b/primitives/manta/Cargo.toml @@ -28,7 +28,7 @@ xcm = { git = 'https://github.com/paritytech/polkadot.git', default-features = f xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "ghzlatarev/polkadot-v0.9.37", default-features = false } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "polkadot-v0.9.37", default-features = false } [features] default = ["std"] diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 90cbf6c78..016257b9c 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -108,8 +108,8 @@ runtime-common = { path = '../common', default-features = false } session-key-primitives = { path = '../../primitives/session-keys', default-features = false } # Third party (vendored) dependencies -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } -orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index cb3b8343b..17d74e937 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -56,8 +56,8 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.37" } # Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } # Self dependencies pallet-asset-manager = { path = '../../pallets/asset-manager' } diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 811892523..4f30200ac 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -52,8 +52,8 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.37" } # Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } # Self dependencies calamari-vesting = { path = '../../pallets/vesting' } diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index 21b9cdc59..9e856cd5a 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -85,8 +85,8 @@ xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-feat xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } # Third party (vendored) dependencies -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } -orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } From 08507a961d1b875da5f1c18cc4608137d760ef79 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Sun, 20 Aug 2023 10:58:02 +0300 Subject: [PATCH 45/69] add limits growth test Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/tests.rs | 83 ++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index e7cc481cf..0866233ca 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -298,4 +298,85 @@ fn start_in_the_future_should_work() { }); } -// todo: test that on_inits which don't roll a day will not increase limits. +#[test] +fn limits_should_grow_appropriately() { + ExtBuilder::default().build().execute_with(|| { + + set_mock_time(Duration::default()); + // add balances to 1,2,3 + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + + // transfer more than limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); + + for _ in 0..1000 { + NativeBarrier::on_initialize(1); + } + + // check that limit has not changed + for k in 1 .. 4 { + let limit = NativeBarrier::get_remaining_xcm_limit(k); + assert_eq!(limit, None); + } + + let daily_limit = 10u128; + let advance_10 = 10 * 86400; + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + Some(daily_limit) + )); + assert_ok!(NativeBarrier::set_start_unix_time( + RawOrigin::Root.into(), + Some(Duration::from_secs(advance_10)) + )); + + assert_ok!(NativeBarrier::add_accounts_to_native_barrier( + RawOrigin::Root.into(), + vec![1, 2, 3] + )); + + + for _ in 0..1000 { + NativeBarrier::on_initialize(1); + } + + assert_eq!(NativeBarrier::get_last_day_processed(), None); + + // check that limit has not changed + for k in 1 .. 4 { + let limit = NativeBarrier::get_remaining_xcm_limit(k); + assert_eq!(limit, Some(daily_limit)); + } + + // roll 10 days + advance_mock_time(Duration::from_secs(advance_10 * 2)); + + for _ in 0..1000 { + NativeBarrier::on_initialize(1); + } + + assert_eq!(NativeBarrier::get_last_day_processed(), Some(10)); + + for k in 1 .. 4 { + let limit = NativeBarrier::get_remaining_xcm_limit(k); + assert_eq!(limit, Some(daily_limit * 10 + daily_limit)); + } + + // roll another 10 days + advance_mock_time(Duration::from_secs(advance_10)); + + for _ in 0..1000 { + NativeBarrier::on_initialize(1); + } + + assert_eq!(NativeBarrier::get_last_day_processed(), Some(20)); + + for k in 1 .. 4 { + let limit = NativeBarrier::get_remaining_xcm_limit(k); + assert_eq!(limit, Some(daily_limit * 20 + daily_limit)); + } + + }); +} \ No newline at end of file From bc4c9f92bf330cd3473db990e81fbc44a97d4401 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Sun, 20 Aug 2023 12:40:55 +0300 Subject: [PATCH 46/69] Clean up tests Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 1 + pallets/native-barrier/src/tests.rs | 175 ++++++++++------------------ 2 files changed, 61 insertions(+), 115 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 49a849ded..4d2024ed4 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -188,6 +188,7 @@ pub mod pallet { /// Caches the last processed day, used to check for start of new days #[pallet::storage] + #[pallet::getter(fn get_last_day_processed)] pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; /// Stores starting unix time for the native barrier logic diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 0866233ca..a3ab67b57 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -89,37 +89,46 @@ fn advance_mock_time(delta: Duration) { }); } +fn initialize_test_environment() -> () { + // add balances to 1,2,3 + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + + // transfer more than limit should work + assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); +} + +fn initialize_native_barrier(daily_limit: u128, start_unix_time: Duration) -> () { + set_mock_time(Duration::default()); + + // add balances to 1,2,3 + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + + assert_ok!(NativeBarrier::set_daily_xcm_limit( + RawOrigin::Root.into(), + Some(daily_limit) + )); + assert_ok!(NativeBarrier::set_start_unix_time( + RawOrigin::Root.into(), + Some(start_unix_time) + )); + assert_ok!(NativeBarrier::add_accounts_to_native_barrier( + RawOrigin::Root.into(), + vec![1, 2, 3] + )); +} + #[test] fn start_in_the_past_should_work() { ExtBuilder::default().build().execute_with(|| { - set_mock_time(Duration::default()); - // add balances to 1,2,3 - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); + initialize_test_environment(); let daily_limit = 10u128; let day_in_secs = 86400; - assert_ok!(NativeBarrier::set_daily_xcm_limit( - RawOrigin::Root.into(), - Some(daily_limit) - )); - assert_ok!(NativeBarrier::set_start_unix_time( - RawOrigin::Root.into(), - Some(Duration::default()) - )); - - // transfer more than limit should work - assert_ok!(Balances::transfer( - RuntimeOrigin::signed(1), - 2, - daily_limit * 2 - )); - - assert_ok!(NativeBarrier::add_accounts_to_native_barrier( - RawOrigin::Root.into(), - vec![1, 2, 3] - )); + initialize_native_barrier(daily_limit, Duration::default()); // transfer under limit should work assert_ok!(Balances::transfer( @@ -198,32 +207,11 @@ fn start_in_the_past_should_work() { #[test] fn start_in_the_future_should_work() { ExtBuilder::default().build().execute_with(|| { - set_mock_time(Duration::default()); - // add balances to 1,2,3 - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); - - // transfer more than limit should work - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); + initialize_test_environment(); let daily_limit = 10u128; - let future_start = 10 * 86400; - let advance_to = 20 * 86400; + let advance_10 = 10 * 86400; let future_days = 10; - assert_ok!(NativeBarrier::set_daily_xcm_limit( - RawOrigin::Root.into(), - Some(daily_limit) - )); - assert_ok!(NativeBarrier::set_start_unix_time( - RawOrigin::Root.into(), - Some(Duration::from_secs(future_start)) - )); - - assert_ok!(NativeBarrier::add_accounts_to_native_barrier( - RawOrigin::Root.into(), - vec![1, 2, 3] - )); // transfer more than limit should work assert_ok!(Balances::transfer( @@ -232,9 +220,11 @@ fn start_in_the_future_should_work() { daily_limit + 5 )); + initialize_native_barrier(daily_limit, Duration::from_secs(advance_10)); + // limit should be multiple of daily limit (now - epoch_start) // roll one day - advance_mock_time(Duration::from_secs(advance_to)); + advance_mock_time(Duration::from_secs(advance_10 * 2)); NativeBarrier::on_initialize(1); // check that limit has been updated @@ -298,85 +288,40 @@ fn start_in_the_future_should_work() { }); } +fn loop_on_init_and_assert_accounts(should_be: Option) { + for _ in 0..1000 { + NativeBarrier::on_initialize(1); + } + + // check that limit has not changed + for k in 1..4 { + let limit = NativeBarrier::get_remaining_xcm_limit(k); + assert_eq!(limit, should_be); + } +} + #[test] fn limits_should_grow_appropriately() { ExtBuilder::default().build().execute_with(|| { - - set_mock_time(Duration::default()); - // add balances to 1,2,3 - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); - - // transfer more than limit should work - assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); - - for _ in 0..1000 { - NativeBarrier::on_initialize(1); - } - - // check that limit has not changed - for k in 1 .. 4 { - let limit = NativeBarrier::get_remaining_xcm_limit(k); - assert_eq!(limit, None); - } + initialize_test_environment(); + loop_on_init_and_assert_accounts(None); + assert_eq!(NativeBarrier::get_last_day_processed(), None); let daily_limit = 10u128; let advance_10 = 10 * 86400; - assert_ok!(NativeBarrier::set_daily_xcm_limit( - RawOrigin::Root.into(), - Some(daily_limit) - )); - assert_ok!(NativeBarrier::set_start_unix_time( - RawOrigin::Root.into(), - Some(Duration::from_secs(advance_10)) - )); - - assert_ok!(NativeBarrier::add_accounts_to_native_barrier( - RawOrigin::Root.into(), - vec![1, 2, 3] - )); - - - for _ in 0..1000 { - NativeBarrier::on_initialize(1); - } + initialize_native_barrier(daily_limit, Duration::from_secs(advance_10)); + loop_on_init_and_assert_accounts(Some(daily_limit)); assert_eq!(NativeBarrier::get_last_day_processed(), None); - // check that limit has not changed - for k in 1 .. 4 { - let limit = NativeBarrier::get_remaining_xcm_limit(k); - assert_eq!(limit, Some(daily_limit)); - } - - // roll 10 days + // roll 20 days (10 days after start) advance_mock_time(Duration::from_secs(advance_10 * 2)); - - for _ in 0..1000 { - NativeBarrier::on_initialize(1); - } - + loop_on_init_and_assert_accounts(Some(daily_limit * 10 + daily_limit)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(10)); - for k in 1 .. 4 { - let limit = NativeBarrier::get_remaining_xcm_limit(k); - assert_eq!(limit, Some(daily_limit * 10 + daily_limit)); - } - // roll another 10 days advance_mock_time(Duration::from_secs(advance_10)); - - for _ in 0..1000 { - NativeBarrier::on_initialize(1); - } - + loop_on_init_and_assert_accounts(Some(daily_limit * 20 + daily_limit)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(20)); - - for k in 1 .. 4 { - let limit = NativeBarrier::get_remaining_xcm_limit(k); - assert_eq!(limit, Some(daily_limit * 20 + daily_limit)); - } - }); -} \ No newline at end of file +} From 76967016b6055472498bce2146d3260886955e2e Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 21 Aug 2023 10:40:24 +0300 Subject: [PATCH 47/69] Revert ignore Signed-off-by: Georgi Zlatarev --- runtime/calamari/src/diff_tx_fees.rs | 1 - runtime/manta/src/diff_tx_fees.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/runtime/calamari/src/diff_tx_fees.rs b/runtime/calamari/src/diff_tx_fees.rs index 8990f0b7e..ecfd8794d 100644 --- a/runtime/calamari/src/diff_tx_fees.rs +++ b/runtime/calamari/src/diff_tx_fees.rs @@ -64,7 +64,6 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { } #[test] -#[ignore] // TODO: remove and fix fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); let mut latest_version = String::new(); diff --git a/runtime/manta/src/diff_tx_fees.rs b/runtime/manta/src/diff_tx_fees.rs index 0c31231b6..dcf596c0a 100644 --- a/runtime/manta/src/diff_tx_fees.rs +++ b/runtime/manta/src/diff_tx_fees.rs @@ -64,7 +64,6 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { } #[test] -#[ignore] // TODO: remove ? fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); let mut latest_version = String::new(); From 4080b84f73ca5a21ec6939b1de9d45fa2a94d78f Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 21 Aug 2023 10:53:01 +0300 Subject: [PATCH 48/69] add docs Signed-off-by: Georgi Zlatarev --- pallets/balances/src/lib.rs | 2 +- pallets/native-barrier/src/tests.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index b02f39372..04923022e 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -248,7 +248,7 @@ pub mod pallet { /// The id type for named reserves. type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; - /// TODO: comment + /// Barrier for native transfers of select accounts type NativeBarrierType: NativeBarrier; } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index a3ab67b57..3c0d57588 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -237,6 +237,18 @@ fn start_in_the_future_should_work() { ), Error::::XcmTransfersLimitExceeded ); + assert_err!( + Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), + Error::::XcmTransfersLimitExceeded + ); + assert_err!( + Balances::transfer_keep_alive( + RuntimeOrigin::signed(1), + 2, + (future_days as u128 + 1) * daily_limit + 1 + ), + Error::::XcmTransfersLimitExceeded + ); // transfer under limit should work assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), From 522f071bd1aee739f97e4b203bf326724e3d4025 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Mon, 21 Aug 2023 10:56:00 +0300 Subject: [PATCH 49/69] check all pallet-balances extriniscs in tests Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/tests.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 3c0d57588..6e8ad4e12 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -141,6 +141,14 @@ fn start_in_the_past_should_work() { Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), Error::::XcmTransfersLimitExceeded ); + assert_err!( + Balances::transfer_keep_alive(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), + Error::::XcmTransfersLimitExceeded + ); + assert_err!( + Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), + Error::::XcmTransfersLimitExceeded + ); // limit should be multiple of daily limit (now - epoch_start) // roll one day @@ -157,6 +165,18 @@ fn start_in_the_past_should_work() { ), Error::::XcmTransfersLimitExceeded ); + assert_err!( + Balances::transfer_keep_alive( + RuntimeOrigin::signed(1), + 2, + daily_limit + daily_limit / 2 + 1 + ), + Error::::XcmTransfersLimitExceeded + ); + assert_err!( + Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), + Error::::XcmTransfersLimitExceeded + ); // transfer under limit should work assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), @@ -237,10 +257,6 @@ fn start_in_the_future_should_work() { ), Error::::XcmTransfersLimitExceeded ); - assert_err!( - Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::XcmTransfersLimitExceeded - ); assert_err!( Balances::transfer_keep_alive( RuntimeOrigin::signed(1), @@ -249,6 +265,11 @@ fn start_in_the_future_should_work() { ), Error::::XcmTransfersLimitExceeded ); + assert_err!( + Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), + Error::::XcmTransfersLimitExceeded + ); + // transfer under limit should work assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), From a85095c706440028193fa6b100dc940680d16d99 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 06:43:58 +0300 Subject: [PATCH 50/69] Remove extra daily limit Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 23 +++++++++-------------- pallets/native-barrier/src/tests.rs | 25 ++++++++++++++++++------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 4d2024ed4..4d96444b3 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -32,7 +32,7 @@ use frame_support::{ensure, pallet_prelude::DispatchResult, traits::UnixTime}; pub use pallet::*; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}, + traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Zero}, FixedPointOperand, Saturating, }; use sp_std::{fmt::Debug, prelude::*}; @@ -121,20 +121,16 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - if let Some(daily_xcm_limit) = DailyXcmLimit::::get() { - if StartUnixTime::::get().is_some() { - for account_id in accounts.iter() { - if !RemainingXcmLimit::::contains_key(account_id) { - RemainingXcmLimit::::insert(account_id, daily_xcm_limit); - } + if StartUnixTime::::get().is_some() && DailyXcmLimit::::get().is_some() { + for account_id in accounts.iter() { + if !RemainingXcmLimit::::contains_key(account_id) { + RemainingXcmLimit::::insert(account_id, T::Balance::zero()); } - - Self::deposit_event(Event::AccountsAddedToBarrier { accounts }); - } else { - return Err(Error::::StartUnixTimeNotSet.into()); } + + Self::deposit_event(Event::AccountsAddedToBarrier { accounts }); } else { - return Err(Error::::XcmDailyLimitNotSet.into()); + return Err(Error::::NativeBarrierNotInitialized.into()); } Ok(().into()) @@ -171,8 +167,7 @@ pub mod pallet { #[pallet::error] pub enum Error { XcmTransfersLimitExceeded, - StartUnixTimeNotSet, - XcmDailyLimitNotSet, + NativeBarrierNotInitialized, } /// Stores daily limit value diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 6e8ad4e12..645dfb200 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -50,7 +50,7 @@ fn extrinsics_as_root_should_work() { ExtBuilder::default().build().execute_with(|| { assert_err!( NativeBarrier::add_accounts_to_native_barrier(RawOrigin::Root.into(), vec![]), - Error::::XcmDailyLimitNotSet + Error::::NativeBarrierNotInitialized ); assert_ok!(NativeBarrier::set_daily_xcm_limit( RawOrigin::Root.into(), @@ -58,7 +58,7 @@ fn extrinsics_as_root_should_work() { )); assert_err!( NativeBarrier::add_accounts_to_native_barrier(RawOrigin::Root.into(), vec![]), - Error::::StartUnixTimeNotSet + Error::::NativeBarrierNotInitialized ); assert_ok!(NativeBarrier::set_start_unix_time( RawOrigin::Root.into(), @@ -128,14 +128,25 @@ fn start_in_the_past_should_work() { let daily_limit = 10u128; let day_in_secs = 86400; + initialize_native_barrier(daily_limit, Duration::default()); + advance_mock_time(Duration::from_secs(day_in_secs)); - // transfer under limit should work + // transfer under limit should not work until next block + assert_err!( + Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2), + Error::::XcmTransfersLimitExceeded + ); + + NativeBarrier::on_initialize(1); + + // transfer under limit should now work assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 2, daily_limit / 2 )); + // transfer more than limit should not work assert_err!( Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), @@ -274,7 +285,7 @@ fn start_in_the_future_should_work() { assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 2, - (future_days as u128 + 1) * daily_limit + future_days as u128 * daily_limit )); assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( @@ -344,17 +355,17 @@ fn limits_should_grow_appropriately() { let advance_10 = 10 * 86400; initialize_native_barrier(daily_limit, Duration::from_secs(advance_10)); - loop_on_init_and_assert_accounts(Some(daily_limit)); + loop_on_init_and_assert_accounts(Some(0)); assert_eq!(NativeBarrier::get_last_day_processed(), None); // roll 20 days (10 days after start) advance_mock_time(Duration::from_secs(advance_10 * 2)); - loop_on_init_and_assert_accounts(Some(daily_limit * 10 + daily_limit)); + loop_on_init_and_assert_accounts(Some(daily_limit * 10)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(10)); // roll another 10 days advance_mock_time(Duration::from_secs(advance_10)); - loop_on_init_and_assert_accounts(Some(daily_limit * 20 + daily_limit)); + loop_on_init_and_assert_accounts(Some(daily_limit * 20)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(20)); }); } From 0bbe97f0c85aaab2b40d47348e88c6a9af3aff66 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 07:31:17 +0300 Subject: [PATCH 51/69] Delete geneiss config unused code Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 49 ++----------------------------- 1 file changed, 2 insertions(+), 47 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 4d96444b3..1352ac9c2 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -111,8 +111,8 @@ pub mod pallet { } /// Add `accounts` to barrier to make them have limited native transfers - /// Sets the in the RemainingXcmLimits storage item, + /// and sets their limit to the amount of one daily limit. Can be used multiple times. #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::add_accounts_to_native_barrier())] pub fn add_accounts_to_native_barrier( @@ -191,34 +191,6 @@ pub mod pallet { #[pallet::getter(fn get_start_unix_time)] pub type StartUnixTime = StorageValue<_, Duration, OptionQuery>; - #[pallet::genesis_config] - pub struct GenesisConfig { - pub barrier_accounts: Vec, - pub daily_limit: T::Balance, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { - barrier_accounts: Default::default(), - daily_limit: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - let now = T::UnixTime::now(); - >::set(Some(now)); - >::set(Some(self.daily_limit)); - for account_id in self.barrier_accounts.iter() { - >::set(account_id, Some(self.daily_limit)); - } - } - } - #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { @@ -245,23 +217,6 @@ pub mod pallet { } } -#[cfg(feature = "std")] -impl GenesisConfig { - /// Direct implementation of `GenesisBuild::build_storage`. - /// - /// Kept in order not to break dependency. - pub fn build_storage(&self) -> Result { - >::build_storage(self) - } - - /// Direct implementation of `GenesisBuild::assimilate_storage`. - /// - /// Kept in order not to break dependency. - pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { - >::assimilate_storage(self, storage) - } -} - impl orml_traits::xcm_transfer::NativeBarrier for Pallet { fn ensure_xcm_transfer_limit_not_exceeded( account_id: &T::AccountId, From def99a53f0b10fcb9479b5c2afbf5ec99bfc9a01 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 08:19:17 +0300 Subject: [PATCH 52/69] Update storage Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/benchmarking.rs | 24 ++--- pallets/native-barrier/src/lib.rs | 100 +++++++----------- pallets/native-barrier/src/tests.rs | 29 ++--- pallets/native-barrier/src/weights.rs | 87 ++++++--------- .../src/weights/pallet_native_barrier.rs | 85 ++++++--------- .../src/weights/pallet_native_barrier.rs | 85 ++++++--------- 6 files changed, 160 insertions(+), 250 deletions(-) diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 3d5a2fbdf..4d53f2921 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -36,9 +36,8 @@ benchmarks! { // add ((now - epoch_start) * daily_limit) + daily_amount for each account on_initialize { let daily_limit = T::Balance::zero(); - let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; let start_unix_time = Duration::default(); - let _ = NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time))?; + let _ = NativeBarrier::::initialize_native_barrier(RawOrigin::Root.into(), Some((daily_limit, start_unix_time)))?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -61,19 +60,13 @@ benchmarks! { } // Worst case scenario would be actually overwriting this simple storage item - set_start_unix_time { - let caller: T::AccountId = whitelisted_caller(); - let start_unix_time = Duration::default(); - }: set_start_unix_time(RawOrigin::Root, Some(start_unix_time)) - - - // Worst case scenario would be actually overwriting this simple storage item - set_daily_xcm_limit { + initialize_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); - }: set_daily_xcm_limit(RawOrigin::Root, Some(daily_limit)) + let start_unix_time = Duration::default(); + }: initialize_native_barrier(RawOrigin::Root, Some((daily_limit, start_unix_time))) verify { - assert_eq!(NativeBarrier::::get_daily_xcm_limit().unwrap(), daily_limit); + assert_eq!(NativeBarrier::::get_configurations().unwrap(), (daily_limit, start_unix_time)); } // Worst case scenario would be actually writing the accounts into the barrier storage item @@ -81,9 +74,8 @@ benchmarks! { add_accounts_to_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); - let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; let start_unix_time = Duration::default(); - let _ = NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time)); + let _ = NativeBarrier::::initialize_native_barrier(RawOrigin::Root.into(), Some((daily_limit, start_unix_time)))?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -103,9 +95,7 @@ benchmarks! { remove_accounts_from_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); - let _ = NativeBarrier::::set_daily_xcm_limit(RawOrigin::Root.into(), Some(daily_limit))?; - let start_unix_time = Duration::default(); - let _ = NativeBarrier::::set_start_unix_time(RawOrigin::Root.into(), Some(start_unix_time))?; + let _ = NativeBarrier::::initialize_native_barrier(RawOrigin::Root.into(), Some((daily_limit, Default::default())))?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 1352ac9c2..7dde3fb39 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -84,29 +84,13 @@ pub mod pallet { /// Can be in the past or the future. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::set_start_unix_time())] - pub fn set_start_unix_time( + pub fn initialize_native_barrier( origin: OriginFor, - start_unix_time: Option, + init: Option<(T::Balance, Duration)>, ) -> DispatchResult { ensure_root(origin)?; - >::set(start_unix_time); - Self::deposit_event(Event::StartUnixTimeSet { start_unix_time }); - Ok(()) - } - - /// Sets the daily limit amount. - /// Can be set to None to turn off the barrier. - #[pallet::call_index(1)] - #[pallet::weight(T::WeightInfo::set_daily_xcm_limit())] - pub fn set_daily_xcm_limit( - origin: OriginFor, - daily_xcm_limit: Option, - ) -> DispatchResult { - ensure_root(origin)?; - >::set(daily_xcm_limit); - Self::deposit_event(Event::DailyXcmLimitSet { - daily_limit: daily_xcm_limit, - }); + >::set(init); + Self::deposit_event(Event::NativeBarrierInitialized { init }); Ok(()) } @@ -121,7 +105,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - if StartUnixTime::::get().is_some() && DailyXcmLimit::::get().is_some() { + if Configurations::::get().is_some() { for account_id in accounts.iter() { if !RemainingXcmLimit::::contains_key(account_id) { RemainingXcmLimit::::insert(account_id, T::Balance::zero()); @@ -158,10 +142,15 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - StartUnixTimeSet { start_unix_time: Option }, - DailyXcmLimitSet { daily_limit: Option }, - AccountsAddedToBarrier { accounts: Vec }, - AccountsRemovedFromBarrier { accounts: Vec }, + NativeBarrierInitialized { + init: Option<(T::Balance, Duration)>, + }, + AccountsAddedToBarrier { + accounts: Vec, + }, + AccountsRemovedFromBarrier { + accounts: Vec, + }, } #[pallet::error] @@ -172,8 +161,8 @@ pub mod pallet { /// Stores daily limit value #[pallet::storage] - #[pallet::getter(fn get_daily_xcm_limit)] - pub type DailyXcmLimit = StorageValue<_, T::Balance, OptionQuery>; + #[pallet::getter(fn get_configurations)] + pub type Configurations = StorageValue<_, (T::Balance, Duration), OptionQuery>; /// Stores remaining limit for each account. Skipped days are accumulated. #[pallet::storage] @@ -186,28 +175,21 @@ pub mod pallet { #[pallet::getter(fn get_last_day_processed)] pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; - /// Stores starting unix time for the native barrier logic - #[pallet::storage] - #[pallet::getter(fn get_start_unix_time)] - pub type StartUnixTime = StorageValue<_, Duration, OptionQuery>; - #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_n: T::BlockNumber) -> Weight { - if let Some(start_unix_time) = StartUnixTime::::get() { - if DailyXcmLimit::::get().is_some() { - let now = T::UnixTime::now(); - if start_unix_time <= now { - let days_since_start = - (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); - - // Default 0 is ok, it would only be used the first time - let last_day_processed = >::get().unwrap_or(0); - - if days_since_start > last_day_processed || days_since_start == 0 { - Self::reset_remaining_xcm_limit(days_since_start - last_day_processed); - >::put(days_since_start); - } + if let Some((_, start_unix_time)) = Configurations::::get() { + let now = T::UnixTime::now(); + if start_unix_time <= now { + let days_since_start = + (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); + + // Default 0 is ok, it would only be used the first time + let last_day_processed = >::get().unwrap_or(0); + + if days_since_start > last_day_processed || days_since_start == 0 { + Self::reset_remaining_xcm_limit(days_since_start - last_day_processed); + >::put(days_since_start); } } } @@ -222,19 +204,17 @@ impl orml_traits::xcm_transfer::NativeBarrier DispatchResult { - if DailyXcmLimit::::get().is_some() { - if let Some(start_unix_time) = >::get() { - let now = T::UnixTime::now(); - if start_unix_time <= now { - if let Some(remaining_limit) = RemainingXcmLimit::::get(account_id) { - ensure!( - amount <= remaining_limit, - Error::::XcmTransfersLimitExceeded - ); - - // If the ensure didn't return an error, update the native transfers - Self::update_xcm_native_transfers(account_id, amount); - } + if let Some((_, start_unix_time)) = >::get() { + let now = T::UnixTime::now(); + if start_unix_time <= now { + if let Some(remaining_limit) = RemainingXcmLimit::::get(account_id) { + ensure!( + amount <= remaining_limit, + Error::::XcmTransfersLimitExceeded + ); + + // If the ensure didn't return an error, update the native transfers + Self::update_xcm_native_transfers(account_id, amount); } } } @@ -257,7 +237,7 @@ impl orml_traits::xcm_transfer::NativeBarrier Pallet { fn reset_remaining_xcm_limit(unprocessed_days: u64) { - if let Some(daily_limit) = >::get() { + if let Some((daily_limit, _)) = >::get() { for (account_id, mut remaining_limit) in RemainingXcmLimit::::iter() { for _ in 0..unprocessed_days { remaining_limit += daily_limit; diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 645dfb200..7f1c0398d 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -27,11 +27,10 @@ use frame_system::RawOrigin; fn extrinsics_as_normal_user_should_not_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - NativeBarrier::set_daily_xcm_limit(RuntimeOrigin::signed(1), Some(10u128)), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - NativeBarrier::set_start_unix_time(RuntimeOrigin::signed(1), Some(Duration::default())), + NativeBarrier::initialize_native_barrier( + RuntimeOrigin::signed(1), + Some((10u128, Default::default())) + ), sp_runtime::DispatchError::BadOrigin ); assert_noop!( @@ -52,17 +51,13 @@ fn extrinsics_as_root_should_work() { NativeBarrier::add_accounts_to_native_barrier(RawOrigin::Root.into(), vec![]), Error::::NativeBarrierNotInitialized ); - assert_ok!(NativeBarrier::set_daily_xcm_limit( - RawOrigin::Root.into(), - Some(10u128) - )); assert_err!( NativeBarrier::add_accounts_to_native_barrier(RawOrigin::Root.into(), vec![]), Error::::NativeBarrierNotInitialized ); - assert_ok!(NativeBarrier::set_start_unix_time( + assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), - Some(Duration::default()) + Some((10, Duration::default())) )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -107,13 +102,9 @@ fn initialize_native_barrier(daily_limit: u128, start_unix_time: Duration) -> () assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 3, 1000, 0)); - assert_ok!(NativeBarrier::set_daily_xcm_limit( - RawOrigin::Root.into(), - Some(daily_limit) - )); - assert_ok!(NativeBarrier::set_start_unix_time( + assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), - Some(start_unix_time) + Some((daily_limit, start_unix_time)) )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -211,7 +202,7 @@ fn start_in_the_past_should_work() { Error::::XcmTransfersLimitExceeded ); - assert_ok!(NativeBarrier::set_daily_xcm_limit( + assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), None )); @@ -308,7 +299,7 @@ fn start_in_the_future_should_work() { Error::::XcmTransfersLimitExceeded ); - assert_ok!(NativeBarrier::set_daily_xcm_limit( + assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), None )); diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index 51157c789..c1c0eb429 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for pallet_native_barrier //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-17, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-08-22, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("manta-dev"), DB CACHE: 1024 // Executed Command: @@ -47,93 +47,76 @@ use manta_primitives::constants::RocksDbWeight; /// Weight functions needed for pallet_native_barrier. pub trait WeightInfo { fn on_initialize() -> Weight; - fn set_start_unix_time() -> Weight; - fn set_daily_xcm_limit() -> Weight; + fn initialize_native_barrier() -> Weight; fn add_accounts_to_native_barrier() -> Weight; fn remove_accounts_from_native_barrier() -> Weight; } /// Weights for pallet_native_barrier using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - // Storage: NativeBarrier StartUnixTime (r:1 w:0) - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) +impl pallet_native_barrier::WeightInfo for SubstrateWeight { + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 45_706 nanoseconds. - Weight::from_ref_time(46_457_000) - .saturating_add(T::DbWeight::get().reads(10)) + // Minimum execution time: 36_940 nanoseconds. + Weight::from_ref_time(37_711_000) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(6)) } - // Storage: NativeBarrier StartUnixTime (r:0 w:1) - fn set_start_unix_time() -> Weight { - // Minimum execution time: 14_287 nanoseconds. - Weight::from_ref_time(14_948_000) + // Storage: NativeBarrier Configurations (r:0 w:1) + fn initialize_native_barrier() -> Weight { + // Minimum execution time: 13_986 nanoseconds. + Weight::from_ref_time(14_678_000) .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) - fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 14_017 nanoseconds. - Weight::from_ref_time(14_628_000) - .saturating_add(T::DbWeight::get().writes(1)) - } - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) - // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_283 nanoseconds. - Weight::from_ref_time(28_994_000) - .saturating_add(T::DbWeight::get().reads(7)) + // Minimum execution time: 25_538 nanoseconds. + Weight::from_ref_time(26_570_000) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } - // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:5) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 16_831 nanoseconds. - Weight::from_ref_time(17_824_000) - .saturating_add(T::DbWeight::get().writes(3)) + // Minimum execution time: 18_354 nanoseconds. + Weight::from_ref_time(19_336_000) + .saturating_add(T::DbWeight::get().writes(5)) } } // For backwards compatibility and tests impl WeightInfo for () { - // Storage: NativeBarrier StartUnixTime (r:1 w:0) - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 45_706 nanoseconds. - Weight::from_ref_time(46_457_000) - .saturating_add(RocksDbWeight::get().reads(10)) + // Minimum execution time: 36_940 nanoseconds. + Weight::from_ref_time(37_711_000) + .saturating_add(RocksDbWeight::get().reads(9)) .saturating_add(RocksDbWeight::get().writes(6)) } - // Storage: NativeBarrier StartUnixTime (r:0 w:1) - fn set_start_unix_time() -> Weight { - // Minimum execution time: 14_287 nanoseconds. - Weight::from_ref_time(14_948_000) + // Storage: NativeBarrier Configurations (r:0 w:1) + fn initialize_native_barrier() -> Weight { + // Minimum execution time: 13_986 nanoseconds. + Weight::from_ref_time(14_678_000) .saturating_add(RocksDbWeight::get().writes(1)) } - // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) - fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 14_017 nanoseconds. - Weight::from_ref_time(14_628_000) - .saturating_add(RocksDbWeight::get().writes(1)) - } - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) - // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_283 nanoseconds. - Weight::from_ref_time(28_994_000) - .saturating_add(RocksDbWeight::get().reads(7)) + // Minimum execution time: 25_538 nanoseconds. + Weight::from_ref_time(26_570_000) + .saturating_add(RocksDbWeight::get().reads(6)) .saturating_add(RocksDbWeight::get().writes(5)) } - // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:5) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 16_831 nanoseconds. - Weight::from_ref_time(17_824_000) - .saturating_add(RocksDbWeight::get().writes(3)) + // Minimum execution time: 18_354 nanoseconds. + Weight::from_ref_time(19_336_000) + .saturating_add(RocksDbWeight::get().writes(5)) } } diff --git a/runtime/calamari/src/weights/pallet_native_barrier.rs b/runtime/calamari/src/weights/pallet_native_barrier.rs index e583cd8ff..c1c0eb429 100644 --- a/runtime/calamari/src/weights/pallet_native_barrier.rs +++ b/runtime/calamari/src/weights/pallet_native_barrier.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for pallet_native_barrier //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-17, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-08-22, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("manta-dev"), DB CACHE: 1024 // Executed Command: @@ -47,8 +47,7 @@ use manta_primitives::constants::RocksDbWeight; /// Weight functions needed for pallet_native_barrier. pub trait WeightInfo { fn on_initialize() -> Weight; - fn set_start_unix_time() -> Weight; - fn set_daily_xcm_limit() -> Weight; + fn initialize_native_barrier() -> Weight; fn add_accounts_to_native_barrier() -> Weight; fn remove_accounts_from_native_barrier() -> Weight; } @@ -56,84 +55,68 @@ pub trait WeightInfo { /// Weights for pallet_native_barrier using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl pallet_native_barrier::WeightInfo for SubstrateWeight { - // Storage: NativeBarrier StartUnixTime (r:1 w:0) - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 45_706 nanoseconds. - Weight::from_ref_time(46_457_000) - .saturating_add(T::DbWeight::get().reads(10)) + // Minimum execution time: 36_940 nanoseconds. + Weight::from_ref_time(37_711_000) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(6)) } - // Storage: NativeBarrier StartUnixTime (r:0 w:1) - fn set_start_unix_time() -> Weight { - // Minimum execution time: 14_287 nanoseconds. - Weight::from_ref_time(14_948_000) + // Storage: NativeBarrier Configurations (r:0 w:1) + fn initialize_native_barrier() -> Weight { + // Minimum execution time: 13_986 nanoseconds. + Weight::from_ref_time(14_678_000) .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) - fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 14_017 nanoseconds. - Weight::from_ref_time(14_628_000) - .saturating_add(T::DbWeight::get().writes(1)) - } - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) - // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_283 nanoseconds. - Weight::from_ref_time(28_994_000) - .saturating_add(T::DbWeight::get().reads(7)) + // Minimum execution time: 25_538 nanoseconds. + Weight::from_ref_time(26_570_000) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } - // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:5) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 16_831 nanoseconds. - Weight::from_ref_time(17_824_000) - .saturating_add(T::DbWeight::get().writes(3)) + // Minimum execution time: 18_354 nanoseconds. + Weight::from_ref_time(19_336_000) + .saturating_add(T::DbWeight::get().writes(5)) } } // For backwards compatibility and tests impl WeightInfo for () { - // Storage: NativeBarrier StartUnixTime (r:1 w:0) - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 45_706 nanoseconds. - Weight::from_ref_time(46_457_000) - .saturating_add(RocksDbWeight::get().reads(10)) + // Minimum execution time: 36_940 nanoseconds. + Weight::from_ref_time(37_711_000) + .saturating_add(RocksDbWeight::get().reads(9)) .saturating_add(RocksDbWeight::get().writes(6)) } - // Storage: NativeBarrier StartUnixTime (r:0 w:1) - fn set_start_unix_time() -> Weight { - // Minimum execution time: 14_287 nanoseconds. - Weight::from_ref_time(14_948_000) + // Storage: NativeBarrier Configurations (r:0 w:1) + fn initialize_native_barrier() -> Weight { + // Minimum execution time: 13_986 nanoseconds. + Weight::from_ref_time(14_678_000) .saturating_add(RocksDbWeight::get().writes(1)) } - // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) - fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 14_017 nanoseconds. - Weight::from_ref_time(14_628_000) - .saturating_add(RocksDbWeight::get().writes(1)) - } - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) - // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_283 nanoseconds. - Weight::from_ref_time(28_994_000) - .saturating_add(RocksDbWeight::get().reads(7)) + // Minimum execution time: 25_538 nanoseconds. + Weight::from_ref_time(26_570_000) + .saturating_add(RocksDbWeight::get().reads(6)) .saturating_add(RocksDbWeight::get().writes(5)) } - // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:5) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 16_831 nanoseconds. - Weight::from_ref_time(17_824_000) - .saturating_add(RocksDbWeight::get().writes(3)) + // Minimum execution time: 18_354 nanoseconds. + Weight::from_ref_time(19_336_000) + .saturating_add(RocksDbWeight::get().writes(5)) } } diff --git a/runtime/manta/src/weights/pallet_native_barrier.rs b/runtime/manta/src/weights/pallet_native_barrier.rs index e583cd8ff..c1c0eb429 100644 --- a/runtime/manta/src/weights/pallet_native_barrier.rs +++ b/runtime/manta/src/weights/pallet_native_barrier.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for pallet_native_barrier //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-17, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-08-22, STEPS: `50`, REPEAT: 40, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("manta-dev"), DB CACHE: 1024 // Executed Command: @@ -47,8 +47,7 @@ use manta_primitives::constants::RocksDbWeight; /// Weight functions needed for pallet_native_barrier. pub trait WeightInfo { fn on_initialize() -> Weight; - fn set_start_unix_time() -> Weight; - fn set_daily_xcm_limit() -> Weight; + fn initialize_native_barrier() -> Weight; fn add_accounts_to_native_barrier() -> Weight; fn remove_accounts_from_native_barrier() -> Weight; } @@ -56,84 +55,68 @@ pub trait WeightInfo { /// Weights for pallet_native_barrier using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl pallet_native_barrier::WeightInfo for SubstrateWeight { - // Storage: NativeBarrier StartUnixTime (r:1 w:0) - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 45_706 nanoseconds. - Weight::from_ref_time(46_457_000) - .saturating_add(T::DbWeight::get().reads(10)) + // Minimum execution time: 36_940 nanoseconds. + Weight::from_ref_time(37_711_000) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(6)) } - // Storage: NativeBarrier StartUnixTime (r:0 w:1) - fn set_start_unix_time() -> Weight { - // Minimum execution time: 14_287 nanoseconds. - Weight::from_ref_time(14_948_000) + // Storage: NativeBarrier Configurations (r:0 w:1) + fn initialize_native_barrier() -> Weight { + // Minimum execution time: 13_986 nanoseconds. + Weight::from_ref_time(14_678_000) .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) - fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 14_017 nanoseconds. - Weight::from_ref_time(14_628_000) - .saturating_add(T::DbWeight::get().writes(1)) - } - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) - // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_283 nanoseconds. - Weight::from_ref_time(28_994_000) - .saturating_add(T::DbWeight::get().reads(7)) + // Minimum execution time: 25_538 nanoseconds. + Weight::from_ref_time(26_570_000) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } - // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:5) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 16_831 nanoseconds. - Weight::from_ref_time(17_824_000) - .saturating_add(T::DbWeight::get().writes(3)) + // Minimum execution time: 18_354 nanoseconds. + Weight::from_ref_time(19_336_000) + .saturating_add(T::DbWeight::get().writes(5)) } } // For backwards compatibility and tests impl WeightInfo for () { - // Storage: NativeBarrier StartUnixTime (r:1 w:0) - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) // Storage: NativeBarrier RemainingXcmLimit (r:6 w:5) fn on_initialize() -> Weight { - // Minimum execution time: 45_706 nanoseconds. - Weight::from_ref_time(46_457_000) - .saturating_add(RocksDbWeight::get().reads(10)) + // Minimum execution time: 36_940 nanoseconds. + Weight::from_ref_time(37_711_000) + .saturating_add(RocksDbWeight::get().reads(9)) .saturating_add(RocksDbWeight::get().writes(6)) } - // Storage: NativeBarrier StartUnixTime (r:0 w:1) - fn set_start_unix_time() -> Weight { - // Minimum execution time: 14_287 nanoseconds. - Weight::from_ref_time(14_948_000) + // Storage: NativeBarrier Configurations (r:0 w:1) + fn initialize_native_barrier() -> Weight { + // Minimum execution time: 13_986 nanoseconds. + Weight::from_ref_time(14_678_000) .saturating_add(RocksDbWeight::get().writes(1)) } - // Storage: NativeBarrier DailyXcmLimit (r:0 w:1) - fn set_daily_xcm_limit() -> Weight { - // Minimum execution time: 14_017 nanoseconds. - Weight::from_ref_time(14_628_000) - .saturating_add(RocksDbWeight::get().writes(1)) - } - // Storage: NativeBarrier DailyXcmLimit (r:1 w:0) - // Storage: NativeBarrier StartUnixTime (r:1 w:0) + // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: NativeBarrier RemainingXcmLimit (r:5 w:5) fn add_accounts_to_native_barrier() -> Weight { - // Minimum execution time: 28_283 nanoseconds. - Weight::from_ref_time(28_994_000) - .saturating_add(RocksDbWeight::get().reads(7)) + // Minimum execution time: 25_538 nanoseconds. + Weight::from_ref_time(26_570_000) + .saturating_add(RocksDbWeight::get().reads(6)) .saturating_add(RocksDbWeight::get().writes(5)) } - // Storage: NativeBarrier RemainingXcmLimit (r:0 w:3) + // Storage: NativeBarrier RemainingXcmLimit (r:0 w:5) fn remove_accounts_from_native_barrier() -> Weight { - // Minimum execution time: 16_831 nanoseconds. - Weight::from_ref_time(17_824_000) - .saturating_add(RocksDbWeight::get().writes(3)) + // Minimum execution time: 18_354 nanoseconds. + Weight::from_ref_time(19_336_000) + .saturating_add(RocksDbWeight::get().writes(5)) } } From bc4abe6e76c2e183dacacbb706cffc0f5692bb05 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 08:22:51 +0300 Subject: [PATCH 53/69] Update index' Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 7dde3fb39..026d60e96 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -80,10 +80,10 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Sets the start unix time for the barrier logic. - /// Can be in the past or the future. + /// Sets the start unix time and daily limit for the barrier logic. + /// Can be in the past or the future. Can be disabled by setting to None. #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::set_start_unix_time())] + #[pallet::weight(T::WeightInfo::initialize_native_barrier())] pub fn initialize_native_barrier( origin: OriginFor, init: Option<(T::Balance, Duration)>, @@ -97,7 +97,7 @@ pub mod pallet { /// Add `accounts` to barrier to make them have limited native transfers /// Sets the in the RemainingXcmLimits storage item, /// and sets their limit to the amount of one daily limit. Can be used multiple times. - #[pallet::call_index(2)] + #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::add_accounts_to_native_barrier())] pub fn add_accounts_to_native_barrier( origin: OriginFor, @@ -121,7 +121,7 @@ pub mod pallet { } /// Remove `accounts` from the barrier's RemainingXcmLimit storage - #[pallet::call_index(3)] + #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::remove_accounts_from_native_barrier())] pub fn remove_accounts_from_native_barrier( origin: OriginFor, From f320489e829b580e104348bc045e52e1bb546625 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 08:28:35 +0300 Subject: [PATCH 54/69] remove xcm mentions 1/2 Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/benchmarking.rs | 16 ++++---- pallets/native-barrier/src/lib.rs | 43 ++++++++++------------ pallets/native-barrier/src/tests.rs | 30 +++++++-------- pallets/native-barrier/src/weights.rs | 2 +- 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 4d53f2921..78123112b 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -31,7 +31,7 @@ const SEED: u32 = 0; benchmarks! { - // Worst case scenario is once per day when the RemainingXcmLimit is updated + // Worst case scenario is once per day when the RemainingLimit is updated // we set the start time as the beginning of the epoch so the on-initialize will // add ((now - epoch_start) * daily_limit) + daily_amount for each account on_initialize { @@ -54,7 +54,7 @@ benchmarks! { for _ in 0..expected_days { total_limit += daily_limit; } - for (account_id, balance) in RemainingXcmLimit::::iter() { + for (account_id, balance) in RemainingLimit::::iter() { assert_eq!(balance, total_limit); } } @@ -86,7 +86,7 @@ benchmarks! { let daily_limit = T::Balance::zero(); }: add_accounts_to_native_barrier(RawOrigin::Root, barrier_addresses) verify { - for (account_id, balance) in RemainingXcmLimit::::iter() { + for (account_id, balance) in RemainingLimit::::iter() { assert_eq!(balance, daily_limit); } } @@ -113,11 +113,11 @@ benchmarks! { ]; }: remove_accounts_from_native_barrier(RawOrigin::Root, remove_addresses) verify { - assert_eq!(None, RemainingXcmLimit::::get(account::("address_0", 0, SEED))); - assert_eq!(None, RemainingXcmLimit::::get(account::("address_1", 0, SEED))); - assert_eq!(None, RemainingXcmLimit::::get(account::("address_2", 0, SEED))); - assert_eq!(None, RemainingXcmLimit::::get(account::("address_3", 0, SEED))); - assert_eq!(None, RemainingXcmLimit::::get(account::("address_4", 0, SEED))); + assert_eq!(None, RemainingLimit::::get(account::("address_0", 0, SEED))); + assert_eq!(None, RemainingLimit::::get(account::("address_1", 0, SEED))); + assert_eq!(None, RemainingLimit::::get(account::("address_2", 0, SEED))); + assert_eq!(None, RemainingLimit::::get(account::("address_3", 0, SEED))); + assert_eq!(None, RemainingLimit::::get(account::("address_4", 0, SEED))); } impl_benchmark_test_suite!( diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 026d60e96..c98341d94 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -95,7 +95,7 @@ pub mod pallet { } /// Add `accounts` to barrier to make them have limited native transfers - /// Sets the in the RemainingXcmLimits storage item, + /// Sets the in the RemainingLimits storage item, /// and sets their limit to the amount of one daily limit. Can be used multiple times. #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::add_accounts_to_native_barrier())] @@ -107,8 +107,8 @@ pub mod pallet { if Configurations::::get().is_some() { for account_id in accounts.iter() { - if !RemainingXcmLimit::::contains_key(account_id) { - RemainingXcmLimit::::insert(account_id, T::Balance::zero()); + if !RemainingLimit::::contains_key(account_id) { + RemainingLimit::::insert(account_id, T::Balance::zero()); } } @@ -120,7 +120,7 @@ pub mod pallet { Ok(().into()) } - /// Remove `accounts` from the barrier's RemainingXcmLimit storage + /// Remove `accounts` from the barrier's RemainingLimit storage #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::remove_accounts_from_native_barrier())] pub fn remove_accounts_from_native_barrier( @@ -130,7 +130,7 @@ pub mod pallet { ensure_root(origin)?; for account_id in accounts.iter() { - RemainingXcmLimit::::remove(account_id); + RemainingLimit::::remove(account_id); } Self::deposit_event(Event::AccountsRemovedFromBarrier { accounts }); @@ -155,7 +155,7 @@ pub mod pallet { #[pallet::error] pub enum Error { - XcmTransfersLimitExceeded, + TransfersLimitExceeded, NativeBarrierNotInitialized, } @@ -166,8 +166,8 @@ pub mod pallet { /// Stores remaining limit for each account. Skipped days are accumulated. #[pallet::storage] - #[pallet::getter(fn get_remaining_xcm_limit)] - pub type RemainingXcmLimit = + #[pallet::getter(fn get_remaining_limit)] + pub type RemainingLimit = StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; /// Caches the last processed day, used to check for start of new days @@ -188,7 +188,7 @@ pub mod pallet { let last_day_processed = >::get().unwrap_or(0); if days_since_start > last_day_processed || days_since_start == 0 { - Self::reset_remaining_xcm_limit(days_since_start - last_day_processed); + Self::reset_remaining_limit(days_since_start - last_day_processed); >::put(days_since_start); } } @@ -207,10 +207,10 @@ impl orml_traits::xcm_transfer::NativeBarrier>::get() { let now = T::UnixTime::now(); if start_unix_time <= now { - if let Some(remaining_limit) = RemainingXcmLimit::::get(account_id) { + if let Some(remaining_limit) = RemainingLimit::::get(account_id) { ensure!( amount <= remaining_limit, - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); // If the ensure didn't return an error, update the native transfers @@ -223,26 +223,23 @@ impl orml_traits::xcm_transfer::NativeBarrier>::mutate_exists( - account_id, - |maybe_remainder| match maybe_remainder { - Some(remainder) => { - *remainder = remainder.saturating_sub(amount); - } - None => {} - }, - ); + >::mutate_exists(account_id, |maybe_remainder| match maybe_remainder { + Some(remainder) => { + *remainder = remainder.saturating_sub(amount); + } + None => {} + }); } } impl Pallet { - fn reset_remaining_xcm_limit(unprocessed_days: u64) { + fn reset_remaining_limit(unprocessed_days: u64) { if let Some((daily_limit, _)) = >::get() { - for (account_id, mut remaining_limit) in RemainingXcmLimit::::iter() { + for (account_id, mut remaining_limit) in RemainingLimit::::iter() { for _ in 0..unprocessed_days { remaining_limit += daily_limit; } - >::insert(&account_id, remaining_limit); + >::insert(&account_id, remaining_limit); } } } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 7f1c0398d..976b9e745 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -63,12 +63,12 @@ fn extrinsics_as_root_should_work() { RawOrigin::Root.into(), vec![1, 2, 3] )); - assert_ne!(NativeBarrier::get_remaining_xcm_limit(1), None); + assert_ne!(NativeBarrier::get_remaining_limit(1), None); assert_ok!(NativeBarrier::remove_accounts_from_native_barrier( RawOrigin::Root.into(), vec![1] )); - assert_eq!(NativeBarrier::get_remaining_xcm_limit(1), None); + assert_eq!(NativeBarrier::get_remaining_limit(1), None); }); } @@ -126,7 +126,7 @@ fn start_in_the_past_should_work() { // transfer under limit should not work until next block assert_err!( Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); NativeBarrier::on_initialize(1); @@ -141,15 +141,15 @@ fn start_in_the_past_should_work() { // transfer more than limit should not work assert_err!( Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_err!( Balances::transfer_keep_alive(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_err!( Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); // limit should be multiple of daily limit (now - epoch_start) @@ -165,7 +165,7 @@ fn start_in_the_past_should_work() { 2, daily_limit + daily_limit / 2 + 1 ), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_err!( Balances::transfer_keep_alive( @@ -173,11 +173,11 @@ fn start_in_the_past_should_work() { 2, daily_limit + daily_limit / 2 + 1 ), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_err!( Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); // transfer under limit should work assert_ok!(Balances::transfer( @@ -199,7 +199,7 @@ fn start_in_the_past_should_work() { )); assert_err!( Balances::transfer(RuntimeOrigin::signed(2), 2, daily_limit * 2 + 1), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_ok!(NativeBarrier::initialize_native_barrier( @@ -257,7 +257,7 @@ fn start_in_the_future_should_work() { 2, (future_days as u128 + 1) * daily_limit + 1 ), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_err!( Balances::transfer_keep_alive( @@ -265,11 +265,11 @@ fn start_in_the_future_should_work() { 2, (future_days as u128 + 1) * daily_limit + 1 ), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_err!( Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); // transfer under limit should work @@ -296,7 +296,7 @@ fn start_in_the_future_should_work() { 2, (future_days as u128 + 1) * daily_limit + 1 ), - Error::::XcmTransfersLimitExceeded + Error::::TransfersLimitExceeded ); assert_ok!(NativeBarrier::initialize_native_barrier( @@ -330,7 +330,7 @@ fn loop_on_init_and_assert_accounts(should_be: Option) { // check that limit has not changed for k in 1..4 { - let limit = NativeBarrier::get_remaining_xcm_limit(k); + let limit = NativeBarrier::get_remaining_limit(k); assert_eq!(limit, should_be); } } diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index c1c0eb429..8eee3ee8a 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -54,7 +54,7 @@ pub trait WeightInfo { /// Weights for pallet_native_barrier using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl pallet_native_barrier::WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:1) From 7f57ad64a348f4d7196b95837179d26832f7faad Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 08:46:17 +0300 Subject: [PATCH 55/69] remove xmc mentions 2/2 Signed-off-by: Georgi Zlatarev --- Cargo.lock | 8 ++++---- pallets/balances/src/lib.rs | 11 ++++------- pallets/manta-pay/src/lib.rs | 4 ++-- pallets/native-barrier/src/lib.rs | 15 ++++++--------- pallets/native-barrier/src/tests.rs | 30 ++++++++++++++--------------- runtime/calamari/src/xcm_config.rs | 2 +- runtime/manta/src/xcm_config.rs | 2 +- 7 files changed, 33 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7becb5641..d0854b2f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6400,7 +6400,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#4ff694c4b1e3c4a187410dddf948d86624601a24" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -6418,7 +6418,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#4ff694c4b1e3c4a187410dddf948d86624601a24" dependencies = [ "frame-support", "parity-scale-codec", @@ -6432,7 +6432,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#4ff694c4b1e3c4a187410dddf948d86624601a24" dependencies = [ "frame-support", "orml-traits", @@ -6446,7 +6446,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#ed7fd79b2368eb0154b5522db304c77ef9c8d57d" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#4ff694c4b1e3c4a187410dddf948d86624601a24" dependencies = [ "cumulus-primitives-core", "frame-support", diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs index 04923022e..720389e1e 100644 --- a/pallets/balances/src/lib.rs +++ b/pallets/balances/src/lib.rs @@ -202,7 +202,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use orml_traits::xcm_transfer::NativeBarrier; + use orml_traits::native_barrier::NativeBarrier; #[pallet::config] pub trait Config: frame_system::Config { @@ -297,7 +297,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - ::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + ::ensure_limit_not_exceeded(&transactor, value)?; >::transfer( &transactor, &dest, @@ -408,7 +408,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - ::ensure_xcm_transfer_limit_not_exceeded(&transactor, value)?; + ::ensure_limit_not_exceeded(&transactor, value)?; >::transfer(&transactor, &dest, value, KeepAlive)?; Ok(().into()) } @@ -442,10 +442,7 @@ pub mod pallet { let reducible_balance = Self::reducible_balance(&transactor, keep_alive); let dest = T::Lookup::lookup(dest)?; let keep_alive = if keep_alive { KeepAlive } else { AllowDeath }; - ::ensure_xcm_transfer_limit_not_exceeded( - &transactor, - reducible_balance, - )?; + ::ensure_limit_not_exceeded(&transactor, reducible_balance)?; >::transfer(&transactor, &dest, reducible_balance, keep_alive)?; Ok(()) } diff --git a/pallets/manta-pay/src/lib.rs b/pallets/manta-pay/src/lib.rs index c777800de..709da42d6 100644 --- a/pallets/manta-pay/src/lib.rs +++ b/pallets/manta-pay/src/lib.rs @@ -118,7 +118,7 @@ pub type FungibleLedgerError = assets::FungibleLedgerError::InvalidAssetId)?; if asset_id == >::NativeAssetId::get() { - ::ensure_xcm_transfer_limit_not_exceeded( + ::ensure_limit_not_exceeded( &origin, asset_value_decode(post.sources[0]), )?; diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index c98341d94..fa0daa2f8 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -155,7 +155,7 @@ pub mod pallet { #[pallet::error] pub enum Error { - TransfersLimitExceeded, + NativeBarrierLimitExceeded, NativeBarrierNotInitialized, } @@ -199,22 +199,19 @@ pub mod pallet { } } -impl orml_traits::xcm_transfer::NativeBarrier for Pallet { - fn ensure_xcm_transfer_limit_not_exceeded( - account_id: &T::AccountId, - amount: T::Balance, - ) -> DispatchResult { +impl orml_traits::native_barrier::NativeBarrier for Pallet { + fn ensure_limit_not_exceeded(account_id: &T::AccountId, amount: T::Balance) -> DispatchResult { if let Some((_, start_unix_time)) = >::get() { let now = T::UnixTime::now(); if start_unix_time <= now { if let Some(remaining_limit) = RemainingLimit::::get(account_id) { ensure!( amount <= remaining_limit, - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); // If the ensure didn't return an error, update the native transfers - Self::update_xcm_native_transfers(account_id, amount); + Self::update_native_barrier(account_id, amount); } } } @@ -222,7 +219,7 @@ impl orml_traits::xcm_transfer::NativeBarrier>::mutate_exists(account_id, |maybe_remainder| match maybe_remainder { Some(remainder) => { *remainder = remainder.saturating_sub(amount); diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 976b9e745..5015e676d 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -126,7 +126,7 @@ fn start_in_the_past_should_work() { // transfer under limit should not work until next block assert_err!( Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); NativeBarrier::on_initialize(1); @@ -141,15 +141,15 @@ fn start_in_the_past_should_work() { // transfer more than limit should not work assert_err!( Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_err!( Balances::transfer_keep_alive(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_err!( Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); // limit should be multiple of daily limit (now - epoch_start) @@ -165,7 +165,7 @@ fn start_in_the_past_should_work() { 2, daily_limit + daily_limit / 2 + 1 ), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_err!( Balances::transfer_keep_alive( @@ -173,11 +173,11 @@ fn start_in_the_past_should_work() { 2, daily_limit + daily_limit / 2 + 1 ), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_err!( Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); // transfer under limit should work assert_ok!(Balances::transfer( @@ -199,7 +199,7 @@ fn start_in_the_past_should_work() { )); assert_err!( Balances::transfer(RuntimeOrigin::signed(2), 2, daily_limit * 2 + 1), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_ok!(NativeBarrier::initialize_native_barrier( @@ -257,19 +257,19 @@ fn start_in_the_future_should_work() { 2, (future_days as u128 + 1) * daily_limit + 1 ), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_err!( Balances::transfer_keep_alive( RuntimeOrigin::signed(1), 2, - (future_days as u128 + 1) * daily_limit + 1 + future_days as u128 * daily_limit + 1 ), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_err!( Balances::transfer_all(RuntimeOrigin::signed(1), 2, false), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); // transfer under limit should work @@ -288,15 +288,15 @@ fn start_in_the_future_should_work() { assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 3, - (future_days as u128 + 1) * daily_limit + 5 + future_days as u128 * daily_limit + 5 )); assert_err!( Balances::transfer( RuntimeOrigin::signed(2), 2, - (future_days as u128 + 1) * daily_limit + 1 + future_days as u128 * daily_limit + 1 ), - Error::::TransfersLimitExceeded + Error::::NativeBarrierLimitExceeded ); assert_ok!(NativeBarrier::initialize_native_barrier( diff --git a/runtime/calamari/src/xcm_config.rs b/runtime/calamari/src/xcm_config.rs index a8ba79d6c..2721e487b 100644 --- a/runtime/calamari/src/xcm_config.rs +++ b/runtime/calamari/src/xcm_config.rs @@ -348,7 +348,7 @@ impl Contains for AssetManager { } } -impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { +impl orml_traits::native_barrier::NativeChecker for NativeBarrier { fn is_native(currency_id: &CurrencyId) -> bool { let asset_location = CurrencyIdtoMultiLocation::>::convert( diff --git a/runtime/manta/src/xcm_config.rs b/runtime/manta/src/xcm_config.rs index 2c0cb660e..514d8a073 100644 --- a/runtime/manta/src/xcm_config.rs +++ b/runtime/manta/src/xcm_config.rs @@ -327,7 +327,7 @@ impl Contains for AssetManager { } } -impl orml_traits::xcm_transfer::NativeChecker for NativeBarrier { +impl orml_traits::native_barrier::NativeChecker for NativeBarrier { fn is_native(currency_id: &CurrencyId) -> bool { let asset_location = CurrencyIdtoMultiLocation::>::convert( From 4643f3faf9dedf92793ba140a4c222dbb0ec8448 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 15:45:48 +0300 Subject: [PATCH 56/69] Clean up Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 163 +++++++++++++++++++----------- 1 file changed, 104 insertions(+), 59 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index fa0daa2f8..0f1fe0245 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -78,6 +78,110 @@ pub mod pallet { #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(PhantomData); + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + NativeBarrierInitialized { + init: Option<(T::Balance, Duration)>, + }, + AccountsAddedToBarrier { + accounts: Vec, + }, + AccountsRemovedFromBarrier { + accounts: Vec, + }, + } + + #[pallet::error] + pub enum Error { + NativeBarrierLimitExceeded, + NativeBarrierNotInitialized, + } + + /// Stores daily limit value + #[pallet::storage] + #[pallet::getter(fn get_configurations)] + pub type Configurations = StorageValue<_, (T::Balance, Duration), OptionQuery>; + + /// Stores remaining limit for each account. Skipped days are accumulated. + #[pallet::storage] + #[pallet::getter(fn get_remaining_limit)] + pub type RemainingLimit = + StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; + + /// Caches the last processed day, used to check for start of new days + #[pallet::storage] + #[pallet::getter(fn get_last_day_processed)] + pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub barrier_accounts: Vec, + pub daily_limit: T::Balance, + pub start_unix_time: Duration, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { + barrier_accounts: vec![], + daily_limit: T::Balance::zero(), + start_unix_time: Duration::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + Configurations::::set(Some((self.daily_limit, self.start_unix_time))); + for account_id in self.barrier_accounts.iter() { + RemainingLimit::::insert(account_id, T::Balance::zero()); + } + } + } + + #[cfg(feature = "std")] + impl GenesisConfig { + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + >::assimilate_storage(self, storage) + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_n: T::BlockNumber) -> Weight { + if let Some((_, start_unix_time)) = Configurations::::get() { + let now = T::UnixTime::now(); + if start_unix_time <= now { + let days_since_start = + (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); + + // Default 0 is ok, it would only be used the first time + let last_day_processed = >::get().unwrap_or(0); + + if days_since_start > last_day_processed || days_since_start == 0 { + Self::reset_remaining_limit(days_since_start - last_day_processed); + >::put(days_since_start); + } + } + } + + T::WeightInfo::on_initialize() + } + } + #[pallet::call] impl Pallet { /// Sets the start unix time and daily limit for the barrier logic. @@ -138,65 +242,6 @@ pub mod pallet { Ok(().into()) } } - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - NativeBarrierInitialized { - init: Option<(T::Balance, Duration)>, - }, - AccountsAddedToBarrier { - accounts: Vec, - }, - AccountsRemovedFromBarrier { - accounts: Vec, - }, - } - - #[pallet::error] - pub enum Error { - NativeBarrierLimitExceeded, - NativeBarrierNotInitialized, - } - - /// Stores daily limit value - #[pallet::storage] - #[pallet::getter(fn get_configurations)] - pub type Configurations = StorageValue<_, (T::Balance, Duration), OptionQuery>; - - /// Stores remaining limit for each account. Skipped days are accumulated. - #[pallet::storage] - #[pallet::getter(fn get_remaining_limit)] - pub type RemainingLimit = - StorageMap<_, Identity, T::AccountId, T::Balance, OptionQuery>; - - /// Caches the last processed day, used to check for start of new days - #[pallet::storage] - #[pallet::getter(fn get_last_day_processed)] - pub type LastDayProcessed = StorageValue<_, u64, OptionQuery>; - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(_n: T::BlockNumber) -> Weight { - if let Some((_, start_unix_time)) = Configurations::::get() { - let now = T::UnixTime::now(); - if start_unix_time <= now { - let days_since_start = - (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); - - // Default 0 is ok, it would only be used the first time - let last_day_processed = >::get().unwrap_or(0); - - if days_since_start > last_day_processed || days_since_start == 0 { - Self::reset_remaining_limit(days_since_start - last_day_processed); - >::put(days_since_start); - } - } - } - - T::WeightInfo::on_initialize() - } - } } impl orml_traits::native_barrier::NativeBarrier for Pallet { From a95fddab572535edce0e738ca32d5a9c9efafdc3 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 22 Aug 2023 17:21:35 +0300 Subject: [PATCH 57/69] Clippy Signed-off-by: Georgi Zlatarev --- pallets/asset-manager/src/mock.rs | 8 ++++---- pallets/balances/src/tests_local.rs | 8 ++++---- pallets/collator-selection/src/mock.rs | 8 ++++---- pallets/farming/src/mock.rs | 8 ++++---- pallets/manta-pay/src/mock.rs | 8 ++++---- pallets/manta-sbt/src/mock.rs | 8 ++++---- pallets/name-service/src/mock.rs | 8 ++++---- pallets/native-barrier/src/tests.rs | 4 ++-- pallets/pallet-lottery/src/mock.rs | 8 ++++---- pallets/parachain-staking/src/mock.rs | 8 ++++---- pallets/randomness/src/mock.rs | 8 ++++---- pallets/tx-pause/src/mock.rs | 8 ++++---- pallets/vesting/src/mock.rs | 8 ++++---- runtime/calamari/src/lib.rs | 4 ++-- .../src/integrations_mock/test_common.rs | 6 +++--- runtime/integration-tests/src/xcm_mock/parachain.rs | 8 ++++---- runtime/integration-tests/src/xcm_mock/relay_chain.rs | 8 ++++---- runtime/manta/src/lib.rs | 4 ++-- 18 files changed, 65 insertions(+), 65 deletions(-) diff --git a/pallets/asset-manager/src/mock.rs b/pallets/asset-manager/src/mock.rs index b39c87f67..48286e7b6 100644 --- a/pallets/asset-manager/src/mock.rs +++ b/pallets/asset-manager/src/mock.rs @@ -110,9 +110,9 @@ impl pallet_assets::Config for Runtime { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -120,7 +120,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/balances/src/tests_local.rs b/pallets/balances/src/tests_local.rs index 0309738fe..d9b0584ab 100644 --- a/pallets/balances/src/tests_local.rs +++ b/pallets/balances/src/tests_local.rs @@ -90,9 +90,9 @@ impl pallet_transaction_payment::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &u64, _amount: u64) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &u64, _amount: u64) {} + fn ensure_limit_not_exceeded( _account_id: &u64, _amount: u64, ) -> frame_support::dispatch::DispatchResult { @@ -100,7 +100,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/collator-selection/src/mock.rs b/pallets/collator-selection/src/mock.rs index ca0026ea3..45f959407 100644 --- a/pallets/collator-selection/src/mock.rs +++ b/pallets/collator-selection/src/mock.rs @@ -81,9 +81,9 @@ impl frame_system::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &u64, _amount: u64) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &u64, _amount: u64) {} + fn ensure_limit_not_exceeded( _account_id: &u64, _amount: u64, ) -> frame_support::dispatch::DispatchResult { @@ -91,7 +91,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index 30637a513..29c55d8ed 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -108,9 +108,9 @@ impl frame_system::Config for Runtime { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -118,7 +118,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/manta-pay/src/mock.rs b/pallets/manta-pay/src/mock.rs index b5b37a955..7e56f576a 100644 --- a/pallets/manta-pay/src/mock.rs +++ b/pallets/manta-pay/src/mock.rs @@ -262,9 +262,9 @@ impl pallet_asset_manager::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId32, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId32, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId32, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -272,7 +272,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNati } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/manta-sbt/src/mock.rs b/pallets/manta-sbt/src/mock.rs index cc2216dcd..d3b6deae6 100644 --- a/pallets/manta-sbt/src/mock.rs +++ b/pallets/manta-sbt/src/mock.rs @@ -107,9 +107,9 @@ impl frame_system::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId32, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId32, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId32, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -117,7 +117,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNati } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/name-service/src/mock.rs b/pallets/name-service/src/mock.rs index 751dc15c2..e669bda6b 100644 --- a/pallets/name-service/src/mock.rs +++ b/pallets/name-service/src/mock.rs @@ -66,9 +66,9 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId32, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId32, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId32, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -76,7 +76,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNati } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 5015e676d..6aa9619b9 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -84,7 +84,7 @@ fn advance_mock_time(delta: Duration) { }); } -fn initialize_test_environment() -> () { +fn initialize_test_environment() { // add balances to 1,2,3 assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 1000, 0)); @@ -94,7 +94,7 @@ fn initialize_test_environment() -> () { assert_ok!(Balances::transfer(RuntimeOrigin::signed(1), 2, 20)); } -fn initialize_native_barrier(daily_limit: u128, start_unix_time: Duration) -> () { +fn initialize_native_barrier(daily_limit: u128, start_unix_time: Duration) { set_mock_time(Duration::default()); // add balances to 1,2,3 diff --git a/pallets/pallet-lottery/src/mock.rs b/pallets/pallet-lottery/src/mock.rs index 3f6a75201..cbba3a5e6 100644 --- a/pallets/pallet-lottery/src/mock.rs +++ b/pallets/pallet-lottery/src/mock.rs @@ -113,9 +113,9 @@ impl frame_system::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -123,7 +123,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index d6deefcce..ebdd55655 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -89,9 +89,9 @@ impl frame_system::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -99,7 +99,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/randomness/src/mock.rs b/pallets/randomness/src/mock.rs index 98048c915..bbcfeceb2 100644 --- a/pallets/randomness/src/mock.rs +++ b/pallets/randomness/src/mock.rs @@ -80,9 +80,9 @@ impl frame_system::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -90,7 +90,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/tx-pause/src/mock.rs b/pallets/tx-pause/src/mock.rs index d8de42e47..cd428b898 100644 --- a/pallets/tx-pause/src/mock.rs +++ b/pallets/tx-pause/src/mock.rs @@ -73,9 +73,9 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -83,7 +83,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/pallets/vesting/src/mock.rs b/pallets/vesting/src/mock.rs index 645924a1e..3f66114e3 100644 --- a/pallets/vesting/src/mock.rs +++ b/pallets/vesting/src/mock.rs @@ -76,9 +76,9 @@ impl frame_system::Config for Test { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -86,7 +86,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index e5c59d25a..fa281e1f1 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -1348,11 +1348,11 @@ impl_runtime_apis! { impl pallet_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { fn get_farming_rewards(who: AccountId, pid: PoolId) -> Vec<(CalamariAssetId, Balance)> { - Farming::get_farming_rewards(&who, pid).unwrap_or(Vec::new()) + Farming::get_farming_rewards(&who, pid).unwrap_or_default() } fn get_gauge_rewards(who: AccountId, pid: PoolId) -> Vec<(CalamariAssetId, Balance)> { - Farming::get_gauge_rewards(&who, pid).unwrap_or(Vec::new()) + Farming::get_gauge_rewards(&who, pid).unwrap_or_default() } } diff --git a/runtime/integration-tests/src/integrations_mock/test_common.rs b/runtime/integration-tests/src/integrations_mock/test_common.rs index ad2fb31bf..96c8a21ba 100644 --- a/runtime/integration-tests/src/integrations_mock/test_common.rs +++ b/runtime/integration-tests/src/integrations_mock/test_common.rs @@ -189,7 +189,7 @@ mod parachain_staking_tests { FERDIE.clone(), ]); // Increase self-bond for everyone but ALICE - for collator in vec![ + for collator in [ BOB.clone(), CHARLIE.clone(), DAVE.clone(), @@ -203,7 +203,7 @@ mod parachain_staking_tests { } // Delegate a large amount of tokens to EVE and ALICE - for collator in vec![EVE.clone(), ALICE.clone()] { + for collator in [EVE.clone(), ALICE.clone()] { assert_ok!(ParachainStaking::delegate( RuntimeOrigin::signed(USER.clone()), collator, @@ -293,7 +293,7 @@ mod parachain_staking_tests { FERDIE.clone(), ]); // Increase bond for everyone but FERDIE - for collator in vec![ + for collator in [ BOB.clone(), CHARLIE.clone(), DAVE.clone(), diff --git a/runtime/integration-tests/src/xcm_mock/parachain.rs b/runtime/integration-tests/src/xcm_mock/parachain.rs index 272f98e62..f7ffca82c 100644 --- a/runtime/integration-tests/src/xcm_mock/parachain.rs +++ b/runtime/integration-tests/src/xcm_mock/parachain.rs @@ -109,9 +109,9 @@ impl frame_system::Config for Runtime { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -119,7 +119,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &CurrencyId) -> bool { true } diff --git a/runtime/integration-tests/src/xcm_mock/relay_chain.rs b/runtime/integration-tests/src/xcm_mock/relay_chain.rs index 01130331b..d453b8317 100644 --- a/runtime/integration-tests/src/xcm_mock/relay_chain.rs +++ b/runtime/integration-tests/src/xcm_mock/relay_chain.rs @@ -79,9 +79,9 @@ impl frame_system::Config for Runtime { } pub struct MockNativeBarrier; -impl orml_traits::xcm_transfer::NativeBarrier for MockNativeBarrier { - fn update_xcm_native_transfers(_account_id: &AccountId, _amount: Balance) {} - fn ensure_xcm_transfer_limit_not_exceeded( +impl orml_traits::native_barrier::NativeBarrier for MockNativeBarrier { + fn update_native_barrier(_account_id: &AccountId, _amount: Balance) {} + fn ensure_limit_not_exceeded( _account_id: &AccountId, _amount: Balance, ) -> frame_support::dispatch::DispatchResult { @@ -89,7 +89,7 @@ impl orml_traits::xcm_transfer::NativeBarrier for MockNative } } -impl orml_traits::xcm_transfer::NativeChecker for MockNativeBarrier { +impl orml_traits::native_barrier::NativeChecker for MockNativeBarrier { fn is_native(_currency_id: &u64) -> bool { true } diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index fe05f3c05..80f9d67c0 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -1320,11 +1320,11 @@ impl_runtime_apis! { impl pallet_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { fn get_farming_rewards(who: AccountId, pid: PoolId) -> Vec<(MantaAssetId, Balance)> { - Farming::get_farming_rewards(&who, pid).unwrap_or(Vec::new()) + Farming::get_farming_rewards(&who, pid).unwrap_or_default() } fn get_gauge_rewards(who: AccountId, pid: PoolId) -> Vec<(MantaAssetId, Balance)> { - Farming::get_gauge_rewards(&who, pid).unwrap_or(Vec::new()) + Farming::get_gauge_rewards(&who, pid).unwrap_or_default() } } From e9c3f20593b47881e71d91cad48f4cce568e41d1 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 23 Aug 2023 08:08:42 +0300 Subject: [PATCH 58/69] Update tx-fees diff files Signed-off-by: Georgi Zlatarev --- runtime/calamari/src/diff_tx_fees.rs | 44 +- .../calamari/tx-fees-data/4.4.0-tx-fees.csv | 736 ++++++++++++++++++ runtime/manta/src/diff_tx_fees.rs | 44 +- runtime/manta/tx-fees-data/4.4.0-tx-fees.csv | 733 +++++++++++++++++ 4 files changed, 1555 insertions(+), 2 deletions(-) create mode 100644 runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv create mode 100644 runtime/manta/tx-fees-data/4.4.0-tx-fees.csv diff --git a/runtime/calamari/src/diff_tx_fees.rs b/runtime/calamari/src/diff_tx_fees.rs index ecfd8794d..f8c782cc3 100644 --- a/runtime/calamari/src/diff_tx_fees.rs +++ b/runtime/calamari/src/diff_tx_fees.rs @@ -105,7 +105,7 @@ fn diff_tx_fees() { frame_support::metadata::RuntimeMetadata::V14(metadata) => metadata.pallets, _ => unreachable!(), }; - assert_eq!(pallets.len(), 39); + assert_eq!(pallets.len(), 40); }); let fee_multipliers = fee_multipliers(); @@ -3169,5 +3169,47 @@ fn calculate_all_current_extrinsic_tx_fee() -> ( )); } + // pallet_native_barrier + { + assert_eq!( + crate::RuntimeCall::get_call_names("NativeBarrier").len(), + 3, + "Please update new extrinsic here." + ); + + let call = crate::RuntimeCall::NativeBarrier( + pallet_native_barrier::Call::initialize_native_barrier { init: None }, + ); + let (dispatch_info, call_len) = get_call_details(&call); + calamari_runtime_calls.push(( + "pallet_native_barrier", + "initialize_native_barrier", + dispatch_info, + call_len, + )); + + let call = crate::RuntimeCall::NativeBarrier( + pallet_native_barrier::Call::add_accounts_to_native_barrier { accounts: vec![] }, + ); + let (dispatch_info, call_len) = get_call_details(&call); + calamari_runtime_calls.push(( + "pallet_native_barrier", + "add_accounts_to_native_barrier", + dispatch_info, + call_len, + )); + + let call = crate::RuntimeCall::NativeBarrier( + pallet_native_barrier::Call::remove_accounts_from_native_barrier { accounts: vec![] }, + ); + let (dispatch_info, call_len) = get_call_details(&call); + calamari_runtime_calls.push(( + "pallet_native_barrier", + "remove_accounts_from_native_barrier", + dispatch_info, + call_len, + )); + } + (calamari_runtime_calls, t) } diff --git a/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv b/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv new file mode 100644 index 000000000..63fe7e58e --- /dev/null +++ b/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv @@ -0,0 +1,736 @@ +module,extrinsic,tx_fee_with_decimal,tx_fee_without_decimal,fee_multiplier +frame_system,remark-length=32,495236584103,0.495236584103,0.0002 +frame_system,remark-length=64,495236584103,0.495236584103,0.0002 +frame_system,set_heap_pages,495221061000,0.495221061,0.0002 +frame_system,set_code,995220000000,0.99522,0.0002 +frame_system,set_code_without_checks,995220000000,0.99522,0.0002 +frame_system,set_storage,495668341581,0.495668341581,0.0002 +frame_system,kill_storage,495765187030,0.49576518703,0.0002 +frame_system,kill_prefix,496188802074,0.496188802074,0.0002 +frame_system,remark_with_event-length=32,495233714184,0.495233714184,0.0002 +frame_system,remark_with_event-length=64,495233714184,0.495233714184,0.0002 +pallet_treasury,propose_spend,495487955000,0.495487955,0.0002 +pallet_treasury,reject_proposal,495200370000,0.49520037,0.0002 +pallet_treasury,approve_proposal,495075579757,0.495075579757,0.0002 +pallet_treasury,spend,495230174000,0.495230174,0.0002 +pallet_treasury,remove_approval,495035698000,0.495035698,0.0002 +pallet_timestamp,set,495036265000,0.495036265,0.0002 +pallet_preimage,note_preimage-length=32,495478847784,0.495478847784,0.0002 +pallet_preimage,note_preimage-length=32,495808942568,0.495808942568,0.0002 +pallet_preimage,unnote_preimage,495479954000,0.495479954,0.0002 +pallet_preimage,request_preimage,495365568000,0.495365568,0.0002 +pallet_preimage,unrequest_preimage,495465126000,0.495465126,0.0002 +pallet_multisig,as_multi_threshold_1,495959895248,0.495959895248,0.0002 +pallet_multisig,as_multi,495904049703,0.495904049703,0.0002 +pallet_multisig,approve_as_multi,495778813262,0.495778813262,0.0002 +pallet_multisig,cancel_as_multi,495803345841,0.495803345841,0.0002 +pallet_membership,add_member,495270000000,0.49527,0.0002 +pallet_membership,remove_member,495270000000,0.49527,0.0002 +pallet_membership,swap_member,495600000000,0.4956,0.0002 +pallet_membership,reset_members,495590000000,0.49559,0.0002 +pallet_membership,change_key,495270000000,0.49527,0.0002 +pallet_membership,set_prime,495270000000,0.49527,0.0002 +pallet_membership,clear_prime,494940000000,0.49494,0.0002 +pallet_democracy,propose,495378902000,0.495378902,0.0002 +pallet_democracy,second,495072267000,0.495072267,0.0002 +pallet_democracy,vote,495518381000,0.495518381,0.0002 +pallet_democracy,emergency_cancel,495203577000,0.495203577,0.0002 +pallet_democracy,external_propose,495109374000,0.495109374,0.0002 +pallet_democracy,external_propose_majority,495045715000,0.495045715,0.0002 +pallet_democracy,external_propose_default,495045725000,0.495045725,0.0002 +pallet_democracy,fast_track,495683337000,0.495683337,0.0002 +pallet_democracy,veto_external,495491460000,0.49549146,0.0002 +pallet_democracy,cancel_referendum,495015367000,0.495015367,0.0002 +pallet_democracy,delegate,508835450468,0.508835450468,0.0002 +pallet_democracy,undelegate,508059878865,0.508059878865,0.0002 +pallet_democracy,clear_public_proposals,494995711000,0.494995711,0.0002 +pallet_democracy,unlock,495642516193,0.495642516193,0.0002 +pallet_democracy,remove_vote,495214206442,0.495214206442,0.0002 +pallet_democracy,remove_other_vote,495544218326,0.495544218326,0.0002 +pallet_democracy,blacklist,496074355000,0.496074355,0.0002 +pallet_democracy,cancel_proposal,495350354000,0.495350354,0.0002 +pallet_collective,set_members,509583916204,0.509583916204,0.0002 +pallet_collective,execute,495428914103,0.495428914103,0.0002 +pallet_collective,propose,495492248312,0.495492248312,0.0002 +pallet_collective,vote,495421021218,0.495421021218,0.0002 +pallet_collective,close,495746009966,0.495746009966,0.0002 +pallet_collective,disapprove_proposal,495575869517,0.495575869517,0.0002 +cumulus_pallet_xcmp_queue,service_overweight,495051000064,0.495051000064,0.0002 +cumulus_pallet_xcmp_queue,suspend_xcm_execution,494990000000,0.49499,0.0002 +cumulus_pallet_xcmp_queue,resume_xcm_execution,494990000000,0.49499,0.0002 +cumulus_pallet_xcmp_queue,update_suspend_threshold,495062837000,0.495062837,0.0002 +cumulus_pallet_xcmp_queue,update_drop_threshold,495062837000,0.495062837,0.0002 +cumulus_pallet_xcmp_queue,update_resume_threshold,495062837000,0.495062837,0.0002 +cumulus_pallet_xcmp_queue,update_threshold_weight,495102783000,0.495102783,0.0002 +cumulus_pallet_xcmp_queue,update_weight_restrict_decay,495102783000,0.495102783,0.0002 +cumulus_pallet_xcmp_queue,update_xcmp_max_individual_weight,495102783000,0.495102783,0.0002 +orml_xtokens,transfer,495260000000,0.49526,0.0002 +orml_xtokens,transfer_multiasset,495070000000,0.49507,0.0002 +orml_xtokens,transfer_with_fee,495420000000,0.49542,0.0002 +orml_xtokens,transfer_multiasset_with_fee,495210000000,0.49521,0.0002 +orml_xtokens,transfer_multicurrencies,495640000000,0.49564,0.0002 +orml_xtokens,transfer_multiassets,495120000000,0.49512,0.0002 +calamari_vesting,vest,495362893000,0.495362893,0.0002 +manta_collator_selection,set_invulnerables,495334837782,0.495334837782,0.0002 +manta_collator_selection,set_desired_candidates,495046158000,0.495046158,0.0002 +manta_collator_selection,set_candidacy_bond,495164180000,0.49516418,0.0002 +manta_collator_selection,register_as_candidate,495179221570,0.49517922157,0.0002 +manta_collator_selection,register_candidate,495499796707,0.495499796707,0.0002 +manta_collator_selection,leave_intent,495060413062,0.495060413062,0.0002 +manta_collator_selection,remove_collator,495409516018,0.495409516018,0.0002 +manta_collator_selection,set_eviction_baseline,495013685000,0.495013685,0.0002 +manta_collator_selection,set_eviction_tolerance,495040747000,0.495040747,0.0002 +pallet_asset_manager,register_asset,495989552000,0.495989552,0.0002 +pallet_asset_manager,update_asset_location,495626475000,0.495626475,0.0002 +pallet_asset_manager,update_asset_metadata,495728106000,0.495728106,0.0002 +pallet_asset_manager,set_units_per_second,495098556000,0.495098556,0.0002 +pallet_asset_manager,mint_asset,495759826000,0.495759826,0.0002 +pallet_asset_manager,set_min_xcm_fee,495081065000,0.495081065,0.0002 +pallet_asset_manager,update_outgoing_filtered_assets,495081519000,0.495081519,0.0002 +pallet_asset_manager,register_lp_asset,496336198000,0.496336198,0.0002 +pallet_asset_manager,permissionless_register_asset,495903605000,0.495903605,0.0002 +pallet_assets,create,495686405000,0.495686405,0.0002 +pallet_assets,force_create,495545322000,0.495545322,0.0002 +pallet_assets,start_destroy,495197486000,0.495197486,0.0002 +pallet_assets,destroy_accounts,761139518000,0.761139518,0.0002 +pallet_assets,destroy_approvals,628394183000,0.628394183,0.0002 +pallet_assets,finish_destroy,495222391000,0.495222391,0.0002 +pallet_assets,mint,495677658000,0.495677658,0.0002 +pallet_assets,burn,495699077000,0.495699077,0.0002 +pallet_assets,transfer,495946472000,0.495946472,0.0002 +pallet_assets,transfer_keep_alive,495940254000,0.495940254,0.0002 +pallet_assets,force_transfer,496280000000,0.49628,0.0002 +pallet_assets,freeze,495558178000,0.495558178,0.0002 +pallet_assets,thaw,495557470000,0.49555747,0.0002 +pallet_assets,freeze_asset,495197176000,0.495197176,0.0002 +pallet_assets,thaw_asset,495196838000,0.495196838,0.0002 +pallet_assets,transfer_ownership,495554006000,0.495554006,0.0002 +pallet_assets,set_team,496186200000,0.4961862,0.0002 +pallet_assets,set_metadata,495895848933,0.495895848933,0.0002 +pallet_assets,clear_metadata,495224987000,0.495224987,0.0002 +pallet_assets,force_set_metadata,495905080757,0.495905080757,0.0002 +pallet_assets,force_clear_metadata,495226169000,0.495226169,0.0002 +pallet_assets,force_asset_status,496545769000,0.496545769,0.0002 +pallet_assets,approve_transfer,495667409000,0.495667409,0.0002 +pallet_assets,cancel_approval,495661896000,0.495661896,0.0002 +pallet_assets,force_cancel_approval,495990207000,0.495990207,0.0002 +pallet_assets,transfer_approved,496412932000,0.496412932,0.0002 +pallet_assets,touch,495337658000,0.495337658,0.0002 +pallet_assets,refund,495347658000,0.495347658,0.0002 +pallet_author_inherent,kick_off_authorship_validation,495108286000,0.495108286,0.0002 +pallet_balances,transfer-1,495404145000,0.495404145,0.0002 +pallet_balances,transfer-1000_000,495434145000,0.495434145,0.0002 +pallet_balances,set_balance,495393053000,0.495393053,0.0002 +pallet_balances,force_transfer,495859215000,0.495859215,0.0002 +pallet_balances,transfer_keep_alive-1,495391952000,0.495391952,0.0002 +pallet_balances,transfer_keep_alive-1000_000,495421952000,0.495421952,0.0002 +pallet_balances,transfer_all,495398137000,0.495398137,0.0002 +pallet_balances,force_unreserve,495527173000,0.495527173,0.0002 +pallet_manta_pay,to_private,536744552000,0.536744552,0.0002 +pallet_manta_pay,private_transfer,568451354000,0.568451354,0.0002 +pallet_manta_pay,to_public,550273559000,0.550273559,0.0002 +pallet_manta_pay,public_transfer,496119832000,0.496119832,0.0002 +pallet_manta_sbt,to_private,536298839000,0.536298839,0.0002 +pallet_manta_sbt,force_to_private,536472517000,0.536472517,0.0002 +pallet_manta_sbt,reserve_sbt,495374480000,0.49537448,0.0002 +pallet_manta_sbt,allowlist_evm_account,495486961000,0.495486961,0.0002 +pallet_manta_sbt,set_next_sbt_id,495176150000,0.49517615,0.0002 +pallet_manta_sbt,remove_allowlist_evm_account,495248155000,0.495248155,0.0002 +pallet_manta_sbt,change_free_reserve_account,495340832000,0.495340832,0.0002 +pallet_manta_sbt,force_mint_sbt_eth,537142245000,0.537142245,0.0002 +pallet_manta_sbt,change_force_account,495353327000,0.495353327,0.0002 +pallet_manta_sbt,mint_sbt_eth,537431745000,0.537431745,0.0002 +pallet_manta_sbt,change_allowlist_account,495336498000,0.495336498,0.0002 +pallet_manta_sbt,update_mint_info,495288604000,0.495288604,0.0002 +pallet_manta_sbt,new_mint_info,495345001000,0.495345001,0.0002 +pallet_parachain_staking,set_staking_expectations,495516633000,0.495516633,0.0002 +pallet_parachain_staking,set_inflation,495203366000,0.495203366,0.0002 +pallet_parachain_staking,set_parachain_bond_account,495356305000,0.495356305,0.0002 +pallet_parachain_staking,set_parachain_bond_account,495356305000,0.495356305,0.0002 +pallet_parachain_staking,set_parachain_bond_reserve_percent,495045931000,0.495045931,0.0002 +pallet_parachain_staking,set_total_selected,495047483000,0.495047483,0.0002 +pallet_parachain_staking,set_collator_commission,495044417000,0.495044417,0.0002 +pallet_parachain_staking,set_blocks_per_round,495122854000,0.495122854,0.0002 +pallet_parachain_staking,join_candidates,495854275235,0.495854275235,0.0002 +pallet_parachain_staking,schedule_leave_candidates,495188345951,0.495188345951,0.0002 +pallet_parachain_staking,execute_leave_candidates,496614827404,0.496614827404,0.0002 +pallet_parachain_staking,cancel_leave_candidates,495185953459,0.495185953459,0.0002 +pallet_parachain_staking,go_offline,495170264000,0.495170264,0.0002 +pallet_parachain_staking,go_offline,495170264000,0.495170264,0.0002 +pallet_parachain_staking,candidate_bond_more,495578456000,0.495578456,0.0002 +pallet_parachain_staking,schedule_candidate_bond_less,495204067000,0.495204067,0.0002 +pallet_parachain_staking,execute_candidate_bond_less,495898385000,0.495898385,0.0002 +pallet_parachain_staking,cancel_candidate_bond_less,495041928000,0.495041928,0.0002 +pallet_parachain_staking,delegate_1_2_3,496195737539,0.496195737539,0.0002 +pallet_parachain_staking,delegate_1_25_3,496203015429,0.496203015429,0.0002 +pallet_parachain_staking,delegate_1_2_100,496222335403,0.496222335403,0.0002 +pallet_parachain_staking,schedule_leave_delegators,495173383000,0.495173383,0.0002 +pallet_parachain_staking,execute_leave_delegators,496707467185,0.496707467185,0.0002 +pallet_parachain_staking,cancel_leave_delegators,495173693000,0.495173693,0.0002 +pallet_parachain_staking,schedule_revoke_delegation,495493589000,0.495493589,0.0002 +pallet_parachain_staking,delegator_bond_more,496195289000,0.496195289,0.0002 +pallet_parachain_staking,schedule_delegator_bond_less,495504323000,0.495504323,0.0002 +pallet_parachain_staking,execute_delegation_request,496615390000,0.49661539,0.0002 +pallet_parachain_staking,cancel_delegation_request,495498232000,0.495498232,0.0002 +pallet_scheduler,cancel,495290142096,0.495290142096,0.0002 +pallet_scheduler,schedule,495239803891,0.495239803891,0.0002 +pallet_scheduler,schedule_named,495771016738,0.495771016738,0.0002 +pallet_scheduler,cancel_named,495558185578,0.495558185578,0.0002 +pallet_scheduler,schedule_after,495479803891,0.495479803891,0.0002 +pallet_scheduler,schedule_named_after,496011016738,0.496011016738,0.0002 +pallet_session,set_keys,496713201000,0.496713201,0.0002 +pallet_session,purge_keys,495340334000,0.495340334,0.0002 +pallet_tx_pause,pause_transaction,495707235000,0.495707235,0.0002 +pallet_tx_pause,unpause_transaction,495698948000,0.495698948,0.0002 +pallet_tx_pause,pause_transactions,496214470000,0.49621447,0.0002 +pallet_tx_pause,unpause_transactions,496197896000,0.496197896,0.0002 +pallet_tx_pause,pause_pallets,503421750000,0.50342175,0.0002 +pallet_tx_pause,unpause_pallets,503421750000,0.50342175,0.0002 +pallet_utility,batch-size=1,495001986439,0.495001986439,0.0002 +pallet_utility,batch-size=32,497125684188,0.497125684188,0.0002 +pallet_utility,as_derivative,497298281188,0.497298281188,0.0002 +pallet_utility,batch_all-size=1,494998351038,0.494998351038,0.0002 +pallet_utility,batch_all-size=32,497009351356,0.497009351356,0.0002 +pallet_utility,dispatch_as,497385768356,0.497385768356,0.0002 +pallet_utility,force_batch,494925118410,0.49492511841,0.0002 +pallet_randomness,set_babe_randomness_results,495284503000,0.495284503,0.0002 +pallet_name_service,register,495586762000,0.495586762,0.0002 +pallet_name_service,accept_register,495512388000,0.495512388,0.0002 +pallet_name_service,set_primary_name,495438492000,0.495438492,0.0002 +pallet_name_service,cancel_pending_register,495409747000,0.495409747,0.0002 +pallet_name_service,remove_register,495437675000,0.495437675,0.0002 +pallet_farming,create_farming_pool,496515458000,0.496515458,0.0002 +pallet_farming,charge,496389696000,0.496389696,0.0002 +pallet_farming,deposit,496105501000,0.496105501,0.0002 +pallet_farming,withdraw,495508597000,0.495508597,0.0002 +pallet_farming,claim,495366723000,0.495366723,0.0002 +pallet_farming,withdraw_claim,495366723000,0.495366723,0.0002 +pallet_farming,close_pool,495050001000,0.495050001,0.0002 +pallet_farming,set_retire_limit,494930001000,0.494930001,0.0002 +pallet_farming,retire_pool,495050001000,0.495050001,0.0002 +pallet_farming,reset_pool,496060001000,0.496060001,0.0002 +pallet_farming,kill_pool,495050001000,0.495050001,0.0002 +pallet_farming,edit_pool,496490001000,0.496490001,0.0002 +pallet_farming,gauge_withdraw,495395220000,0.49539522,0.0002 +pallet_farming,force_gauge_claim,495050001000,0.495050001,0.0002 +pallet_lottery,deposit,497127379480,0.49712737948,0.0002 +pallet_lottery,request_withdraw,496394120403,0.496394120403,0.0002 +pallet_lottery,claim_my_winnings,495470892425,0.495470892425,0.0002 +pallet_lottery,rebalance_stake,494890000000,0.49489,0.0002 +pallet_lottery,start_lottery,495311718000,0.495311718,0.0002 +pallet_lottery,stop_lottery,495171919000,0.495171919,0.0002 +pallet_lottery,draw_lottery,495296111000,0.495296111,0.0002 +pallet_lottery,process_matured_withdrawals,495007101000,0.495007101,0.0002 +pallet_lottery,liquidate_lottery,494890000000,0.49489,0.0002 +pallet_lottery,set_min_deposit,495184766000,0.495184766,0.0002 +pallet_lottery,set_min_withdraw,495155916000,0.495155916,0.0002 +pallet_lottery,set_gas_reserve,495155750000,0.49515575,0.0002 +zenlink_protocol,set_fee_receiver,495363111000,0.495363111,0.0002 +zenlink_protocol,set_fee_point,495036392000,0.495036392,0.0002 +zenlink_protocol,transfer,495351000000,0.495351,0.0002 +zenlink_protocol,transfer,495457424000,0.495457424,0.0002 +zenlink_protocol,add_liquidity,498968018000,0.498968018,0.0002 +zenlink_protocol,remove_liquidity,497562898000,0.497562898,0.0002 +zenlink_protocol,swap_exact_assets_for_assets,496570262000,0.496570262,0.0002 +zenlink_protocol,swap_assets_for_exact_assets,496570543000,0.496570543,0.0002 +zenlink_protocol,bootstrap_create,496490665000,0.496490665,0.0002 +zenlink_protocol,bootstrap_contribute,496071203000,0.496071203,0.0002 +zenlink_protocol,bootstrap_claim,498344570000,0.49834457,0.0002 +zenlink_protocol,bootstrap_end,499159387000,0.499159387,0.0002 +zenlink_protocol,bootstrap_update,496532242000,0.496532242,0.0002 +zenlink_protocol,bootstrap_refund,495995301000,0.495995301,0.0002 +zenlink_protocol,bootstrap_charge_reward,495840000000,0.49584,0.0002 +zenlink_protocol,bootstrap_withdraw_reward,495570000000,0.49557,0.0002 +pallet_native_barrier,initialize_native_barrier,495014678000,0.495014678,0.0002 +pallet_native_barrier,add_accounts_to_native_barrier,495576570000,0.49557657,0.0002 +pallet_native_barrier,remove_accounts_from_native_barrier,495419336000,0.495419336,0.0002 +frame_system,remark-length=32,511804103000,0.511804103,0.2 +frame_system,remark-length=64,511804103000,0.511804103,0.2 +frame_system,set_heap_pages,746031000000,0.746031,0.2 +frame_system,set_code,500495220000000,500.49521999999996,0.2 +frame_system,set_code_without_checks,500495220000000,500.49521999999996,0.2 +frame_system,set_storage,603901581000,0.603901581,0.2 +frame_system,kill_storage,700747030000,0.70074703,0.2 +frame_system,kill_prefix,1424062074000,1.424062074,0.2 +frame_system,remark_with_event-length=32,508934184000,0.508934184,0.2 +frame_system,remark_with_event-length=64,508934184000,0.508934184,0.2 +pallet_treasury,propose_spend,753185000000,0.753185,0.2 +pallet_treasury,reject_proposal,795270000000,0.79527,0.2 +pallet_treasury,approve_proposal,670479757000,0.670479757,0.2 +pallet_treasury,spend,495404000000,0.495404,0.2 +pallet_treasury,remove_approval,630598000000,0.630598,0.2 +pallet_timestamp,set,631165000000,0.631165,0.2 +pallet_preimage,note_preimage-length=32,754067784000,0.754067784,0.2 +pallet_preimage,note_preimage-length=32,754492568000,0.754492568,0.2 +pallet_preimage,unnote_preimage,765164000000,0.765164,0.2 +pallet_preimage,request_preimage,650778000000,0.650778,0.2 +pallet_preimage,unrequest_preimage,750336000000,0.750336,0.2 +pallet_multisig,as_multi_threshold_1,895455248000,0.895455248,0.2 +pallet_multisig,as_multi,789659703000,0.789659703,0.2 +pallet_multisig,approve_as_multi,684403262000,0.684403262,0.2 +pallet_multisig,cancel_as_multi,658985841000,0.658985841,0.2 +pallet_membership,add_member,545220000000,0.54522,0.2 +pallet_membership,remove_member,545220000000,0.54522,0.2 +pallet_membership,swap_member,545550000000,0.54555,0.2 +pallet_membership,reset_members,545540000000,0.54554,0.2 +pallet_membership,change_key,545220000000,0.54522,0.2 +pallet_membership,set_prime,545220000000,0.54522,0.2 +pallet_membership,clear_prime,544890000000,0.54489,0.2 +pallet_democracy,propose,923852000000,0.923852,0.2 +pallet_democracy,second,667167000000,0.667167,0.2 +pallet_democracy,vote,933461000000,0.933461,0.2 +pallet_democracy,emergency_cancel,768507000000,0.768507,0.2 +pallet_democracy,external_propose,664314000000,0.664314,0.2 +pallet_democracy,external_propose_majority,600655000000,0.600655,0.2 +pallet_democracy,external_propose_default,600665000000,0.600665,0.2 +pallet_democracy,fast_track,888627000000,0.888627,0.2 +pallet_democracy,veto_external,776670000000,0.77667,0.2 +pallet_democracy,cancel_referendum,610267000000,0.610267,0.2 +pallet_democracy,delegate,13940840468000,13.940840468,0.2 +pallet_democracy,undelegate,13664768865000,13.664768865,0.2 +pallet_democracy,clear_public_proposals,600601000000,0.600601,0.2 +pallet_democracy,unlock,917736193000,0.917736193,0.2 +pallet_democracy,remove_vote,779136442000,0.779136442,0.2 +pallet_democracy,remove_other_vote,779478326000,0.779478326,0.2 +pallet_democracy,blacklist,1309615000000,1.309615,0.2 +pallet_democracy,cancel_proposal,945254000000,0.945254,0.2 +pallet_collective,set_members,14169826204000,14.169826204,0.2 +pallet_collective,execute,993844103000,0.993844103,0.2 +pallet_collective,propose,1047188312000,1.047188312,0.2 +pallet_collective,vote,686251218000,0.686251218,0.2 +pallet_collective,close,991259966000,0.991259966,0.2 +pallet_collective,disapprove_proposal,861079517000,0.861079517,0.2 +cumulus_pallet_xcmp_queue,service_overweight,496050064000,0.496050064,0.2 +cumulus_pallet_xcmp_queue,suspend_xcm_execution,594890000000,0.59489,0.2 +cumulus_pallet_xcmp_queue,resume_xcm_execution,594890000000,0.59489,0.2 +cumulus_pallet_xcmp_queue,update_suspend_threshold,627767000000,0.627767,0.2 +cumulus_pallet_xcmp_queue,update_drop_threshold,627767000000,0.627767,0.2 +cumulus_pallet_xcmp_queue,update_resume_threshold,627767000000,0.627767,0.2 +cumulus_pallet_xcmp_queue,update_threshold_weight,627753000000,0.627753,0.2 +cumulus_pallet_xcmp_queue,update_weight_restrict_decay,627753000000,0.627753,0.2 +cumulus_pallet_xcmp_queue,update_xcmp_max_individual_weight,627753000000,0.627753,0.2 +orml_xtokens,transfer,495260000000,0.49526,0.2 +orml_xtokens,transfer_multiasset,495070000000,0.49507,0.2 +orml_xtokens,transfer_with_fee,495420000000,0.49542,0.2 +orml_xtokens,transfer_multiasset_with_fee,495210000000,0.49521,0.2 +orml_xtokens,transfer_multicurrencies,495640000000,0.49564,0.2 +orml_xtokens,transfer_multiassets,495120000000,0.49512,0.2 +calamari_vesting,vest,967783000000,0.967783,0.2 +manta_collator_selection,set_invulnerables,610057782000,0.610057782,0.2 +manta_collator_selection,set_desired_candidates,611088000000,0.611088,0.2 +manta_collator_selection,set_candidacy_bond,609230000000,0.60923,0.2 +manta_collator_selection,register_as_candidate,784111570000,0.78411157,0.2 +manta_collator_selection,register_candidate,785006707000,0.785006707,0.2 +manta_collator_selection,leave_intent,665303062000,0.665303062,0.2 +manta_collator_selection,remove_collator,694726018000,0.694726018,0.2 +manta_collator_selection,set_eviction_baseline,608585000000,0.608585,0.2 +manta_collator_selection,set_eviction_tolerance,635647000000,0.635647,0.2 +pallet_asset_manager,register_asset,1254782000000,1.254782,0.2 +pallet_asset_manager,update_asset_location,1191405000000,1.191405,0.2 +pallet_asset_manager,update_asset_metadata,863466000000,0.863466,0.2 +pallet_asset_manager,set_units_per_second,683466000000,0.683466,0.2 +pallet_asset_manager,mint_asset,875206000000,0.875206,0.2 +pallet_asset_manager,set_min_xcm_fee,645995000000,0.645995,0.2 +pallet_asset_manager,update_outgoing_filtered_assets,646449000000,0.646449,0.2 +pallet_asset_manager,register_lp_asset,1311718000000,1.311718,0.2 +pallet_asset_manager,permissionless_register_asset,1318685000000,1.318685,0.2 +pallet_assets,create,641945000000,0.641945,0.2 +pallet_assets,force_create,640722000000,0.640722,0.2 +pallet_assets,start_destroy,642536000000,0.642536,0.2 +pallet_assets,destroy_accounts,266584568000000,266.584568,0.2 +pallet_assets,destroy_approvals,133839233000000,133.839233,0.2 +pallet_assets,finish_destroy,667441000000,0.667441,0.2 +pallet_assets,mint,783048000000,0.783048,0.2 +pallet_assets,burn,804467000000,0.804467,0.2 +pallet_assets,transfer,1051862000000,1.051862,0.2 +pallet_assets,transfer_keep_alive,1045644000000,1.045644,0.2 +pallet_assets,force_transfer,1055720000000,1.05572,0.2 +pallet_assets,freeze,673558000000,0.673558,0.2 +pallet_assets,thaw,672850000000,0.67285,0.2 +pallet_assets,freeze_asset,642226000000,0.642226,0.2 +pallet_assets,thaw_asset,641888000000,0.641888,0.2 +pallet_assets,transfer_ownership,669386000000,0.669386,0.2 +pallet_assets,set_team,642240000000,0.64224,0.2 +pallet_assets,set_metadata,671568933000,0.671568933,0.2 +pallet_assets,clear_metadata,670037000000,0.670037,0.2 +pallet_assets,force_set_metadata,670810757000,0.670810757,0.2 +pallet_assets,force_clear_metadata,671219000000,0.671219,0.2 +pallet_assets,force_asset_status,642169000000,0.642169,0.2 +pallet_assets,approve_transfer,772799000000,0.772799,0.2 +pallet_assets,cancel_approval,777276000000,0.777276,0.2 +pallet_assets,force_cancel_approval,775917000000,0.775917,0.2 +pallet_assets,transfer_approved,1188652000000,1.188652,0.2 +pallet_assets,touch,782708000000,0.782708,0.2 +pallet_assets,refund,782718000000,0.782718,0.2 +pallet_author_inherent,kick_off_authorship_validation,713176000000,0.713176,0.2 +pallet_balances,transfer-1,669375000000,0.669375,0.2 +pallet_balances,transfer-1000_000,669405000000,0.669405,0.2 +pallet_balances,set_balance,648293000000,0.648293,0.2 +pallet_balances,force_transfer,794775000000,0.794775,0.2 +pallet_balances,transfer_keep_alive-1,657182000000,0.657182,0.2 +pallet_balances,transfer_keep_alive-1000_000,657212000000,0.657212,0.2 +pallet_balances,transfer_all,663367000000,0.663367,0.2 +pallet_balances,force_unreserve,642553000000,0.642553,0.2 +pallet_manta_pay,to_private,41000792000000,41.000792,0.2 +pallet_manta_pay,private_transfer,72707594000000,72.707594,0.2 +pallet_manta_pay,to_public,54529799000000,54.529799000000004,0.2 +pallet_manta_pay,public_transfer,925522000000,0.925522,0.2 +pallet_manta_sbt,to_private,40515119000000,40.515119000000006,0.2 +pallet_manta_sbt,force_to_private,40359127000000,40.359127,0.2 +pallet_manta_sbt,reserve_sbt,969380000000,0.96938,0.2 +pallet_manta_sbt,allowlist_evm_account,852091000000,0.852091,0.2 +pallet_manta_sbt,set_next_sbt_id,611210000000,0.61121,0.2 +pallet_manta_sbt,remove_allowlist_evm_account,613285000000,0.613285,0.2 +pallet_manta_sbt,change_free_reserve_account,616052000000,0.616052,0.2 +pallet_manta_sbt,force_mint_sbt_eth,40489395000000,40.489395,0.2 +pallet_manta_sbt,change_force_account,628547000000,0.628547,0.2 +pallet_manta_sbt,mint_sbt_eth,40569105000000,40.56910499999999,0.2 +pallet_manta_sbt,change_allowlist_account,611718000000,0.611718,0.2 +pallet_manta_sbt,update_mint_info,743644000000,0.743644,0.2 +pallet_manta_sbt,new_mint_info,840001000000,0.840001,0.2 +pallet_parachain_staking,set_staking_expectations,642003000000,0.642003,0.2 +pallet_parachain_staking,set_inflation,688376000000,0.688376,0.2 +pallet_parachain_staking,set_parachain_bond_account,641515000000,0.641515,0.2 +pallet_parachain_staking,set_parachain_bond_account,641515000000,0.641515,0.2 +pallet_parachain_staking,set_parachain_bond_reserve_percent,640831000000,0.640831,0.2 +pallet_parachain_staking,set_total_selected,642383000000,0.642383,0.2 +pallet_parachain_staking,set_collator_commission,639317000000,0.639317,0.2 +pallet_parachain_staking,set_blocks_per_round,717754000000,0.717754,0.2 +pallet_parachain_staking,join_candidates,1439185235000,1.439185235,0.2 +pallet_parachain_staking,schedule_leave_candidates,783245951000,0.783245951,0.2 +pallet_parachain_staking,execute_leave_candidates,1890047404000,1.890047404,0.2 +pallet_parachain_staking,cancel_leave_candidates,780853459000,0.780853459,0.2 +pallet_parachain_staking,go_offline,775154000000,0.775154,0.2 +pallet_parachain_staking,go_offline,775154000000,0.775154,0.2 +pallet_parachain_staking,candidate_bond_more,1173356000000,1.173356,0.2 +pallet_parachain_staking,schedule_candidate_bond_less,649117000000,0.649117,0.2 +pallet_parachain_staking,execute_candidate_bond_less,1183595000000,1.183595,0.2 +pallet_parachain_staking,cancel_candidate_bond_less,646818000000,0.646818,0.2 +pallet_parachain_staking,delegate_1_2_3,1450977539000,1.450977539,0.2 +pallet_parachain_staking,delegate_1_25_3,1458255429000,1.458255429,0.2 +pallet_parachain_staking,delegate_1_2_100,1467585403000,1.467585403,0.2 +pallet_parachain_staking,schedule_leave_delegators,778273000000,0.778273,0.2 +pallet_parachain_staking,execute_leave_delegators,1982687185000,1.982687185,0.2 +pallet_parachain_staking,cancel_leave_delegators,778583000000,0.778583,0.2 +pallet_parachain_staking,schedule_revoke_delegation,778799000000,0.778799,0.2 +pallet_parachain_staking,delegator_bond_more,1470509000000,1.470509,0.2 +pallet_parachain_staking,schedule_delegator_bond_less,779543000000,0.779543,0.2 +pallet_parachain_staking,execute_delegation_request,1580920000000,1.58092,0.2 +pallet_parachain_staking,cancel_delegation_request,783442000000,0.783442,0.2 +pallet_scheduler,cancel,815112096000,0.815112096,0.2 +pallet_scheduler,schedule,684853891000,0.684853891,0.2 +pallet_scheduler,schedule_named,816466738000,0.816466738,0.2 +pallet_scheduler,cancel_named,843395578000,0.843395578,0.2 +pallet_scheduler,schedule_after,685093891000,0.685093891,0.2 +pallet_scheduler,schedule_named_after,816706738000,0.816706738,0.2 +pallet_session,set_keys,1029381000000,1.029381,0.2 +pallet_session,purge_keys,945224000000,0.945224,0.2 +pallet_tx_pause,pause_transaction,652785000000,0.652785,0.2 +pallet_tx_pause,unpause_transaction,644498000000,0.644498,0.2 +pallet_tx_pause,pause_transactions,810370000000,0.81037,0.2 +pallet_tx_pause,unpause_transactions,793796000000,0.793796,0.2 +pallet_tx_pause,pause_pallets,8357310000000,8.35731,0.2 +pallet_tx_pause,unpause_pallets,8357310000000,8.35731,0.2 +pallet_utility,batch-size=1,566916439000,0.566916439,0.2 +pallet_utility,batch-size=32,1761544188000,1.761544188,0.2 +pallet_utility,as_derivative,1894181188000,1.894181188,0.2 +pallet_utility,batch_all-size=1,563281038000,0.563281038,0.2 +pallet_utility,batch_all-size=32,1645211356000,1.645211356,0.2 +pallet_utility,dispatch_as,1661988356000,1.661988356,0.2 +pallet_utility,force_batch,520018410000,0.52001841,0.2 +pallet_randomness,set_babe_randomness_results,889393000000,0.889393,0.2 +pallet_name_service,register,822022000000,0.822022,0.2 +pallet_name_service,accept_register,747648000000,0.747648,0.2 +pallet_name_service,set_primary_name,673752000000,0.673752,0.2 +pallet_name_service,cancel_pending_register,645007000000,0.645007,0.2 +pallet_name_service,remove_register,672935000000,0.672935,0.2 +pallet_farming,create_farming_pool,971498000000,0.971498,0.2 +pallet_farming,charge,1185396000000,1.185396,0.2 +pallet_farming,deposit,1320781000000,1.320781,0.2 +pallet_farming,withdraw,783817000000,0.783817,0.2 +pallet_farming,claim,811773000000,0.811773,0.2 +pallet_farming,withdraw_claim,811773000000,0.811773,0.2 +pallet_farming,close_pool,495051000000,0.495051,0.2 +pallet_farming,set_retire_limit,494931000000,0.494931,0.2 +pallet_farming,retire_pool,495051000000,0.495051,0.2 +pallet_farming,reset_pool,496061000000,0.496061,0.2 +pallet_farming,kill_pool,495051000000,0.495051,0.2 +pallet_farming,edit_pool,496491000000,0.496491,0.2 +pallet_farming,gauge_withdraw,840270000000,0.84027,0.2 +pallet_farming,force_gauge_claim,495051000000,0.495051,0.2 +pallet_lottery,deposit,2572429480000,2.57242948,0.2 +pallet_lottery,request_withdraw,1839170403000,1.839170403,0.2 +pallet_lottery,claim_my_winnings,1075782425000,1.075782425,0.2 +pallet_lottery,rebalance_stake,494890000000,0.49489,0.2 +pallet_lottery,start_lottery,916608000000,0.916608,0.2 +pallet_lottery,stop_lottery,776809000000,0.776809,0.2 +pallet_lottery,draw_lottery,901001000000,0.901001,0.2 +pallet_lottery,process_matured_withdrawals,611991000000,0.611991,0.2 +pallet_lottery,liquidate_lottery,494890000000,0.49489,0.2 +pallet_lottery,set_min_deposit,629816000000,0.629816,0.2 +pallet_lottery,set_min_withdraw,600966000000,0.600966,0.2 +pallet_lottery,set_gas_reserve,600800000000,0.6008,0.2 +zenlink_protocol,set_fee_receiver,638331000000,0.638331,0.2 +zenlink_protocol,set_fee_point,631292000000,0.631292,0.2 +zenlink_protocol,transfer,496350000000,0.49635,0.2 +zenlink_protocol,transfer,802574000000,0.802574,0.2 +zenlink_protocol,add_liquidity,4263218000000,4.263218,0.2 +zenlink_protocol,remove_liquidity,2548408000000,2.548408,0.2 +zenlink_protocol,swap_exact_assets_for_assets,1425902000000,1.425902,0.2 +zenlink_protocol,swap_assets_for_exact_assets,1426183000000,1.426183,0.2 +zenlink_protocol,bootstrap_create,846805000000,0.846805,0.2 +zenlink_protocol,bootstrap_contribute,1366403000000,1.366403,0.2 +zenlink_protocol,bootstrap_claim,3360050000000,3.36005,0.2 +zenlink_protocol,bootstrap_end,4504537000000,4.504537,0.2 +zenlink_protocol,bootstrap_update,878392000000,0.878392,0.2 +zenlink_protocol,bootstrap_refund,1340451000000,1.340451,0.2 +zenlink_protocol,bootstrap_charge_reward,595740000000,0.59574,0.2 +zenlink_protocol,bootstrap_withdraw_reward,595470000000,0.59547,0.2 +pallet_native_barrier,initialize_native_barrier,609578000000,0.609578,0.2 +pallet_native_barrier,add_accounts_to_native_barrier,1171470000000,1.17147,0.2 +pallet_native_barrier,remove_accounts_from_native_barrier,1014236000000,1.014236,0.2 +frame_system,remark-length=32,578140515000,0.578140515,1 +frame_system,remark-length=64,578140515000,0.578140515,1 +frame_system,set_heap_pages,1750275000000,1.750275,1 +frame_system,set_code,2500495220000000,2500.49522,1 +frame_system,set_code_without_checks,2500495220000000,2500.49522,1 +frame_system,set_storage,1037267905000,1.037267905,1 +frame_system,kill_storage,1521495150000,1.52149515,1 +frame_system,kill_prefix,5139270370000,5.13927037,1 +frame_system,remark_with_event-length=32,563790920000,0.56379092,1 +frame_system,remark_with_event-length=64,563790920000,0.56379092,1 +pallet_treasury,propose_spend,1785005000000,1.785005,1 +pallet_treasury,reject_proposal,1996750000000,1.99675,1 +pallet_treasury,approve_proposal,1372798785000,1.372798785,1 +pallet_treasury,spend,496100000000,0.4961,1 +pallet_treasury,remove_approval,1173390000000,1.17339,1 +pallet_timestamp,set,1176225000000,1.176225,1 +pallet_preimage,note_preimage-length=32,1789458920000,1.78945892,1 +pallet_preimage,note_preimage-length=32,1790262840000,1.79026284,1 +pallet_preimage,unnote_preimage,1844980000000,1.84498,1 +pallet_preimage,request_preimage,1273050000000,1.27305,1 +pallet_preimage,unrequest_preimage,1770840000000,1.77084,1 +pallet_multisig,as_multi_threshold_1,2495036240000,2.49503624,1 +pallet_multisig,as_multi,1965858515000,1.965858515,1 +pallet_multisig,approve_as_multi,1439656310000,1.43965631,1 +pallet_multisig,cancel_as_multi,1312369205000,1.312369205,1 +pallet_membership,add_member,745220000000,0.74522,1 +pallet_membership,remove_member,745220000000,0.74522,1 +pallet_membership,swap_member,745550000000,0.74555,1 +pallet_membership,reset_members,745540000000,0.74554,1 +pallet_membership,change_key,745220000000,0.74522,1 +pallet_membership,set_prime,745220000000,0.74522,1 +pallet_membership,clear_prime,744890000000,0.74489,1 +pallet_democracy,propose,2639460000000,2.63946,1 +pallet_democracy,second,1356235000000,1.356235,1 +pallet_democracy,vote,2686985000000,2.686985,1 +pallet_democracy,emergency_cancel,1862815000000,1.862815,1 +pallet_democracy,external_propose,1341810000000,1.34181,1 +pallet_democracy,external_propose_majority,1023515000000,1.023515,1 +pallet_democracy,external_propose_default,1023565000000,1.023565,1 +pallet_democracy,fast_track,2461975000000,2.461975,1 +pallet_democracy,veto_external,1902510000000,1.90251,1 +pallet_democracy,cancel_referendum,1071735000000,1.071735,1 +pallet_democracy,delegate,67722642340000,67.72264234,1 +pallet_democracy,undelegate,66344284325000,66.344284325,1 +pallet_democracy,clear_public_proposals,1023445000000,1.023445,1 +pallet_democracy,unlock,2607800965000,2.607800965,1 +pallet_democracy,remove_vote,1915962210000,1.91596221,1 +pallet_democracy,remove_other_vote,1916351630000,1.91635163,1 +pallet_democracy,blacklist,4567035000000,4.567035,1 +pallet_democracy,cancel_proposal,2746670000000,2.74667,1 +pallet_collective,set_members,68865491020000,68.86549102000001,1 +pallet_collective,execute,2989500515000,2.989500515,1 +pallet_collective,propose,3256181560000,3.25618156,1 +pallet_collective,vote,1450336090000,1.45033609,1 +pallet_collective,close,2975299830000,2.97529983,1 +pallet_collective,disapprove_proposal,2324557585000,2.324557585,1 +cumulus_pallet_xcmp_queue,service_overweight,500050320000,0.50005032,1 +cumulus_pallet_xcmp_queue,suspend_xcm_execution,994890000000,0.99489,1 +cumulus_pallet_xcmp_queue,resume_xcm_execution,994890000000,0.99489,1 +cumulus_pallet_xcmp_queue,update_suspend_threshold,1159115000000,1.159115,1 +cumulus_pallet_xcmp_queue,update_drop_threshold,1159115000000,1.159115,1 +cumulus_pallet_xcmp_queue,update_resume_threshold,1159115000000,1.159115,1 +cumulus_pallet_xcmp_queue,update_threshold_weight,1158885000000,1.158885,1 +cumulus_pallet_xcmp_queue,update_weight_restrict_decay,1158885000000,1.158885,1 +cumulus_pallet_xcmp_queue,update_xcmp_max_individual_weight,1158885000000,1.158885,1 +orml_xtokens,transfer,495260000000,0.49526,1 +orml_xtokens,transfer_multiasset,495070000000,0.49507,1 +orml_xtokens,transfer_with_fee,495420000000,0.49542,1 +orml_xtokens,transfer_multiasset_with_fee,495210000000,0.49521,1 +orml_xtokens,transfer_multicurrencies,495640000000,0.49564,1 +orml_xtokens,transfer_multiassets,495120000000,0.49512,1 +calamari_vesting,vest,2859355000000,2.859355,1 +manta_collator_selection,set_invulnerables,1069408910000,1.06940891,1 +manta_collator_selection,set_desired_candidates,1075720000000,1.07572,1 +manta_collator_selection,set_candidacy_bond,1065950000000,1.06595,1 +manta_collator_selection,register_as_candidate,1940997850000,1.94099785,1 +manta_collator_selection,register_candidate,1944193535000,1.944193535,1 +manta_collator_selection,leave_intent,1346955310000,1.34695531,1 +manta_collator_selection,remove_collator,1492790090000,1.49279009,1 +manta_collator_selection,set_eviction_baseline,1063325000000,1.063325,1 +manta_collator_selection,set_eviction_tolerance,1198635000000,1.198635,1 +pallet_asset_manager,register_asset,4292990000000,4.29299,1 +pallet_asset_manager,update_asset_location,3977305000000,3.977305,1 +pallet_asset_manager,update_asset_metadata,2335890000000,2.33589,1 +pallet_asset_manager,set_units_per_second,1437690000000,1.43769,1 +pallet_asset_manager,mint_asset,2394510000000,2.39451,1 +pallet_asset_manager,set_min_xcm_fee,1250255000000,1.250255,1 +pallet_asset_manager,update_outgoing_filtered_assets,1252525000000,1.252525,1 +pallet_asset_manager,register_lp_asset,4576510000000,4.57651,1 +pallet_asset_manager,permissionless_register_asset,4613105000000,4.613105,1 +pallet_assets,create,1227565000000,1.227565,1 +pallet_assets,force_create,1222010000000,1.22201,1 +pallet_assets,start_destroy,1232480000000,1.23248,1 +pallet_assets,destroy_accounts,1330942640000000,1330.94264,1 +pallet_assets,destroy_approvals,667215965000000,667.215965,1 +pallet_assets,finish_destroy,1357005000000,1.357005,1 +pallet_assets,mint,1933680000000,1.93368,1 +pallet_assets,burn,2040775000000,2.040775,1 +pallet_assets,transfer,3277750000000,3.27775,1 +pallet_assets,transfer_keep_alive,3246660000000,3.24666,1 +pallet_assets,force_transfer,3295720000000,3.29572,1 +pallet_assets,freeze,1386270000000,1.38627,1 +pallet_assets,thaw,1382730000000,1.38273,1 +pallet_assets,freeze_asset,1230930000000,1.23093,1 +pallet_assets,thaw_asset,1229240000000,1.22924,1 +pallet_assets,transfer_ownership,1365410000000,1.36541,1 +pallet_assets,set_team,1227040000000,1.22704,1 +pallet_assets,set_metadata,1374964665000,1.374964665,1 +pallet_assets,clear_metadata,1369985000000,1.369985,1 +pallet_assets,force_set_metadata,1371133785000,1.371133785,1 +pallet_assets,force_clear_metadata,1375895000000,1.375895,1 +pallet_assets,force_asset_status,1225245000000,1.225245,1 +pallet_assets,approve_transfer,1882435000000,1.882435,1 +pallet_assets,cancel_approval,1904860000000,1.90486,1 +pallet_assets,force_cancel_approval,1896745000000,1.896745,1 +pallet_assets,transfer_approved,3960380000000,3.96038,1 +pallet_assets,touch,1933340000000,1.93334,1 +pallet_assets,refund,1933350000000,1.93335,1 +pallet_author_inherent,kick_off_authorship_validation,1586320000000,1.58632,1 +pallet_balances,transfer-1,1365955000000,1.365955,1 +pallet_balances,transfer-1000_000,1365985000000,1.365985,1 +pallet_balances,set_balance,1260505000000,1.260505,1 +pallet_balances,force_transfer,1991635000000,1.991635,1 +pallet_balances,transfer_keep_alive-1,1304990000000,1.30499,1 +pallet_balances,transfer_keep_alive-1000_000,1305020000000,1.30502,1 +pallet_balances,transfer_all,1335915000000,1.335915,1 +pallet_balances,force_unreserve,1231245000000,1.231245,1 +pallet_manta_pay,to_private,203019000000000,203.019,1 +pallet_manta_pay,private_transfer,361553010000000,361.55301,1 +pallet_manta_pay,to_public,270664035000000,270.664035,1 +pallet_manta_pay,public_transfer,2644850000000,2.64485,1 +pallet_manta_sbt,to_private,200590475000000,200.590475,1 +pallet_manta_sbt,force_to_private,199809195000000,199.809195,1 +pallet_manta_sbt,reserve_sbt,2867300000000,2.8673,1 +pallet_manta_sbt,allowlist_evm_account,2279935000000,2.279935,1 +pallet_manta_sbt,set_next_sbt_id,1075810000000,1.07581,1 +pallet_manta_sbt,remove_allowlist_evm_account,1085905000000,1.085905,1 +pallet_manta_sbt,change_free_reserve_account,1099380000000,1.09938,1 +pallet_manta_sbt,force_mint_sbt_eth,200458375000000,200.45837500000002,1 +pallet_manta_sbt,change_force_account,1161855000000,1.161855,1 +pallet_manta_sbt,mint_sbt_eth,200856085000000,200.856085,1 +pallet_manta_sbt,change_allowlist_account,1077710000000,1.07771,1 +pallet_manta_sbt,update_mint_info,1738060000000,1.73806,1 +pallet_manta_sbt,new_mint_info,2220005000000,2.220005,1 +pallet_parachain_staking,set_staking_expectations,1228535000000,1.228535,1 +pallet_parachain_staking,set_inflation,1461840000000,1.46184,1 +pallet_parachain_staking,set_parachain_bond_account,1226735000000,1.226735,1 +pallet_parachain_staking,set_parachain_bond_account,1226735000000,1.226735,1 +pallet_parachain_staking,set_parachain_bond_reserve_percent,1224555000000,1.224555,1 +pallet_parachain_staking,set_total_selected,1232315000000,1.232315,1 +pallet_parachain_staking,set_collator_commission,1216985000000,1.216985,1 +pallet_parachain_staking,set_blocks_per_round,1609170000000,1.60917,1 +pallet_parachain_staking,join_candidates,5216286175000,5.2162861750000005,1 +pallet_parachain_staking,schedule_leave_candidates,1936629755000,1.936629755,1 +pallet_parachain_staking,execute_leave_candidates,7469357020000,7.46935702,1 +pallet_parachain_staking,cancel_leave_candidates,1924667295000,1.924667295,1 +pallet_parachain_staking,go_offline,1896210000000,1.89621,1 +pallet_parachain_staking,go_offline,1896210000000,1.89621,1 +pallet_parachain_staking,candidate_bond_more,3887180000000,3.88718,1 +pallet_parachain_staking,schedule_candidate_bond_less,1265385000000,1.265385,1 +pallet_parachain_staking,execute_candidate_bond_less,3937135000000,3.937135,1 +pallet_parachain_staking,cancel_candidate_bond_less,1254530000000,1.25453,1 +pallet_parachain_staking,delegate_1_2_3,5273927695000,5.273927695,1 +pallet_parachain_staking,delegate_1_25_3,5310317145000,5.310317144999999,1 +pallet_parachain_staking,delegate_1_2_100,5356927015000,5.356927015,1 +pallet_parachain_staking,schedule_leave_delegators,1911805000000,1.911805,1 +pallet_parachain_staking,execute_leave_delegators,7932555925000,7.932555924999999,1 +pallet_parachain_staking,cancel_leave_delegators,1913355000000,1.913355,1 +pallet_parachain_staking,schedule_revoke_delegation,1913155000000,1.913155,1 +pallet_parachain_staking,delegator_bond_more,5371665000000,5.371665,1 +pallet_parachain_staking,schedule_delegator_bond_less,1916835000000,1.916835,1 +pallet_parachain_staking,execute_delegation_request,5922480000000,5.92248,1 +pallet_parachain_staking,cancel_delegation_request,1936370000000,1.93637,1 +pallet_scheduler,cancel,2095680480000,2.09568048,1 +pallet_scheduler,schedule,1444069455000,1.444069455,1 +pallet_scheduler,schedule_named,2100533690000,2.10053369,1 +pallet_scheduler,cancel_named,2236137890000,2.23613789,1 +pallet_scheduler,schedule_after,1444309455000,1.444309455,1 +pallet_scheduler,schedule_named_after,2100773690000,2.10077369,1 +pallet_session,set_keys,3162185000000,3.162185,1 +pallet_session,purge_keys,2746560000000,2.74656,1 +pallet_tx_pause,pause_transaction,1281725000000,1.281725,1 +pallet_tx_pause,unpause_transaction,1240290000000,1.24029,1 +pallet_tx_pause,pause_transactions,2068250000000,2.06825,1 +pallet_tx_pause,unpause_transactions,1985380000000,1.98538,1 +pallet_tx_pause,pause_pallets,39804310000000,39.80431,1 +pallet_tx_pause,unpause_pallets,39804310000000,39.80431,1 +pallet_utility,batch-size=1,854862195000,0.854862195,1 +pallet_utility,batch-size=32,6824280940000,6.82428094,1 +pallet_utility,as_derivative,7487305940000,7.48730594,1 +pallet_utility,batch_all-size=1,836685190000,0.83668519,1 +pallet_utility,batch_all-size=32,6242616780000,6.24261678,1 +pallet_utility,dispatch_as,6325061780000,6.32506178,1 +pallet_utility,force_batch,620492050000,0.62049205,1 +pallet_randomness,set_babe_randomness_results,2467405000000,2.467405,1 +pallet_name_service,register,2129070000000,2.12907,1 +pallet_name_service,accept_register,1757200000000,1.7572,1 +pallet_name_service,set_primary_name,1387720000000,1.38772,1 +pallet_name_service,cancel_pending_register,1243995000000,1.243995,1 +pallet_name_service,remove_register,1383635000000,1.383635,1 +pallet_farming,create_farming_pool,2873330000000,2.87333,1 +pallet_farming,charge,3944180000000,3.94418,1 +pallet_farming,deposit,4622785000000,4.622785,1 +pallet_farming,withdraw,1938205000000,1.938205,1 +pallet_farming,claim,2078665000000,2.078665,1 +pallet_farming,withdraw_claim,2078665000000,2.078665,1 +pallet_farming,close_pool,495055000000,0.495055,1 +pallet_farming,set_retire_limit,494935000000,0.494935,1 +pallet_farming,retire_pool,495055000000,0.495055,1 +pallet_farming,reset_pool,496065000000,0.496065,1 +pallet_farming,kill_pool,495055000000,0.495055,1 +pallet_farming,edit_pool,496495000000,0.496495,1 +pallet_farming,gauge_withdraw,2221150000000,2.22115,1 +pallet_farming,force_gauge_claim,495055000000,0.495055,1 +pallet_lottery,deposit,10881947400000,10.8819474,1 +pallet_lottery,request_withdraw,7215652015000,7.215652015000001,1 +pallet_lottery,claim_my_winnings,3399352125000,3.399352125,1 +pallet_lottery,rebalance_stake,494890000000,0.49489,1 +pallet_lottery,start_lottery,2603480000000,2.60348,1 +pallet_lottery,stop_lottery,1904485000000,1.904485,1 +pallet_lottery,draw_lottery,2525445000000,2.525445,1 +pallet_lottery,process_matured_withdrawals,1080395000000,1.080395,1 +pallet_lottery,liquidate_lottery,494890000000,0.49489,1 +pallet_lottery,set_min_deposit,1168880000000,1.16888,1 +pallet_lottery,set_min_withdraw,1024630000000,1.02463,1 +pallet_lottery,set_gas_reserve,1023800000000,1.0238,1 +zenlink_protocol,set_fee_receiver,1210775000000,1.210775,1 +zenlink_protocol,set_fee_point,1176860000000,1.17686,1 +zenlink_protocol,transfer,500350000000,0.50035,1 +zenlink_protocol,transfer,2032270000000,2.03227,1 +zenlink_protocol,add_liquidity,19335290000000,19.33529,1 +zenlink_protocol,remove_liquidity,10760000000000,10.76,1 +zenlink_protocol,swap_exact_assets_for_assets,5146950000000,5.14695,1 +zenlink_protocol,swap_assets_for_exact_assets,5148355000000,5.148355,1 +zenlink_protocol,bootstrap_create,2249465000000,2.249465,1 +zenlink_protocol,bootstrap_contribute,4851215000000,4.851215,1 +zenlink_protocol,bootstrap_claim,14818330000000,14.81833,1 +zenlink_protocol,bootstrap_end,20542085000000,20.542085,1 +zenlink_protocol,bootstrap_update,2407360000000,2.40736,1 +zenlink_protocol,bootstrap_refund,4721655000000,4.721655,1 +zenlink_protocol,bootstrap_charge_reward,995740000000,0.99574,1 +zenlink_protocol,bootstrap_withdraw_reward,995470000000,0.99547,1 +pallet_native_barrier,initialize_native_barrier,1068290000000,1.06829,1 +pallet_native_barrier,add_accounts_to_native_barrier,3877750000000,3.87775,1 +pallet_native_barrier,remove_accounts_from_native_barrier,3091580000000,3.09158,1 diff --git a/runtime/manta/src/diff_tx_fees.rs b/runtime/manta/src/diff_tx_fees.rs index dcf596c0a..4f0891c00 100644 --- a/runtime/manta/src/diff_tx_fees.rs +++ b/runtime/manta/src/diff_tx_fees.rs @@ -105,7 +105,7 @@ fn diff_tx_fees() { frame_support::metadata::RuntimeMetadata::V14(metadata) => metadata.pallets, _ => unreachable!(), }; - assert_eq!(pallets.len(), 39); + assert_eq!(pallets.len(), 40); }); let fee_multipliers = fee_multipliers(); @@ -3156,5 +3156,47 @@ fn calculate_all_current_extrinsic_tx_fee() -> ( )); } + // pallet_native_barrier + { + assert_eq!( + crate::RuntimeCall::get_call_names("NativeBarrier").len(), + 3, + "Please update new extrinsic here." + ); + + let call = crate::RuntimeCall::NativeBarrier( + pallet_native_barrier::Call::initialize_native_barrier { init: None }, + ); + let (dispatch_info, call_len) = get_call_details(&call); + calamari_runtime_calls.push(( + "pallet_native_barrier", + "initialize_native_barrier", + dispatch_info, + call_len, + )); + + let call = crate::RuntimeCall::NativeBarrier( + pallet_native_barrier::Call::add_accounts_to_native_barrier { accounts: vec![] }, + ); + let (dispatch_info, call_len) = get_call_details(&call); + calamari_runtime_calls.push(( + "pallet_native_barrier", + "add_accounts_to_native_barrier", + dispatch_info, + call_len, + )); + + let call = crate::RuntimeCall::NativeBarrier( + pallet_native_barrier::Call::remove_accounts_from_native_barrier { accounts: vec![] }, + ); + let (dispatch_info, call_len) = get_call_details(&call); + calamari_runtime_calls.push(( + "pallet_native_barrier", + "remove_accounts_from_native_barrier", + dispatch_info, + call_len, + )); + } + (calamari_runtime_calls, t) } diff --git a/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv b/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv new file mode 100644 index 000000000..d0627cfa3 --- /dev/null +++ b/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv @@ -0,0 +1,733 @@ +module,extrinsic,tx_fee_with_decimal,tx_fee_without_decimal,fee_multiplier +frame_system,remark-length=32,5298832146460000,0.00529883214646,0.0002 +frame_system,remark-length=64,5298832146460000,0.00529883214646,0.0002 +frame_system,set_heap_pages,5051034450000000,0.00505103445,0.0002 +frame_system,set_code,10298700000000000,0.0102987,0.0002 +frame_system,set_code_without_checks,10298700000000000,0.0102987,0.0002 +frame_system,set_storage,5639746997510000,0.00563974699751,0.0002 +frame_system,kill_storage,5640750464760000,0.00564075046476,0.0002 +frame_system,kill_prefix,5347861573090000,0.00534786157309,0.0002 +frame_system,remark_with_event-length=32,5298835865040000,0.00529883586504,0.0002 +frame_system,remark_with_event-length=64,5298835865040000,0.00529883586504,0.0002 +pallet_treasury,propose_spend,5311280870000000,0.00531128087,0.0002 +pallet_treasury,reject_proposal,4981742030000000,0.00498174203,0.0002 +pallet_treasury,approve_proposal,4980459314970000,0.00498045931497,0.0002 +pallet_treasury,spend,5308701710000000,0.00530870171,0.0002 +pallet_treasury,remove_approval,4980055430000000,0.00498005543,0.0002 +pallet_timestamp,set,4980037830000000,0.00498003783,0.0002 +pallet_preimage,note_preimage-length=32,5301290792080000,0.00530129079208,0.0002 +pallet_preimage,note_preimage-length=32,5631291734160000,0.00563129173416,0.0002 +pallet_preimage,unnote_preimage,5291369270000000,0.00529136927,0.0002 +pallet_preimage,request_preimage,5290231710000000,0.00529023171,0.0002 +pallet_preimage,unrequest_preimage,5291230180000000,0.00529123018,0.0002 +pallet_multisig,as_multi_threshold_1,5642675964490000,0.00564267596449,0.0002 +pallet_multisig,as_multi,5691632704520000,0.00569163270452,0.0002 +pallet_multisig,approve_as_multi,5670593606370000,0.00567059360637,0.0002 +pallet_multisig,cancel_as_multi,5720336406670000,0.00572033640667,0.0002 +pallet_membership,add_member,5299200000000000,0.0052992,0.0002 +pallet_membership,remove_member,5299200000000000,0.0052992,0.0002 +pallet_membership,swap_member,5629200000000000,0.0056292,0.0002 +pallet_membership,reset_members,5619200000000000,0.0056192,0.0002 +pallet_membership,change_key,5299200000000000,0.0052992,0.0002 +pallet_membership,set_prime,5299200000000000,0.0052992,0.0002 +pallet_membership,clear_prime,4969200000000000,0.0049692,0.0002 +pallet_democracy,propose,5032996150000000,0.00503299615,0.0002 +pallet_democracy,second,4980427850000000,0.00498042785,0.0002 +pallet_democracy,vote,5163099650000000,0.00516309965,0.0002 +pallet_democracy,emergency_cancel,5011449160000000,0.00501144916,0.0002 +pallet_democracy,external_propose,5020391910000000,0.00502039191,0.0002 +pallet_democracy,external_propose_majority,5019756600000000,0.0050197566,0.0002 +pallet_democracy,external_propose_default,5019752930000000,0.00501975293,0.0002 +pallet_democracy,fast_track,5372439790000000,0.00537243979,0.0002 +pallet_democracy,veto_external,5291524150000000,0.00529152415,0.0002 +pallet_democracy,cancel_referendum,4979854120000000,0.00497985412,0.0002 +pallet_democracy,delegate,5603100511750000,0.00560310051175,0.0002 +pallet_democracy,undelegate,5100368590710000,0.00510036859071,0.0002 +pallet_democracy,clear_public_proposals,4969756880000000,0.00496975688,0.0002 +pallet_democracy,unlock,5302928523210000,0.00530292852321,0.0002 +pallet_democracy,remove_vote,5011552070440000,0.00501155207044,0.0002 +pallet_democracy,remove_other_vote,5341551218650000,0.00534155121865,0.0002 +pallet_democracy,blacklist,5346860120000000,0.00534686012,0.0002 +pallet_democracy,cancel_proposal,4983213060000000,0.00498321306,0.0002 +pallet_collective,set_members,6125485107120000,0.00612548510712,0.0002 +pallet_collective,execute,5013732935810000,0.00501373293581,0.0002 +pallet_collective,propose,5024232816700000,0.0050242328167,0.0002 +pallet_collective,vote,5310619517400000,0.0053106195174,0.0002 +pallet_collective,close,5333667460860000,0.00533366746086,0.0002 +pallet_collective,disapprove_proposal,5292365846660000,0.00529236584666,0.0002 +cumulus_pallet_xcmp_queue,service_overweight,5128710000640000,0.00512871000064,0.0002 +cumulus_pallet_xcmp_queue,suspend_xcm_execution,4969700000000000,0.0049697,0.0002 +cumulus_pallet_xcmp_queue,resume_xcm_execution,4969700000000000,0.0049697,0.0002 +cumulus_pallet_xcmp_queue,update_suspend_threshold,5010025090000000,0.00501002509,0.0002 +cumulus_pallet_xcmp_queue,update_drop_threshold,5010025090000000,0.00501002509,0.0002 +cumulus_pallet_xcmp_queue,update_resume_threshold,5010025090000000,0.00501002509,0.0002 +cumulus_pallet_xcmp_queue,update_threshold_weight,5050121450000000,0.00505012145,0.0002 +cumulus_pallet_xcmp_queue,update_weight_restrict_decay,5050121450000000,0.00505012145,0.0002 +cumulus_pallet_xcmp_queue,update_xcmp_max_individual_weight,5050121450000000,0.00505012145,0.0002 +orml_xtokens,transfer,5338700000000000,0.0053387,0.0002 +orml_xtokens,transfer_multiasset,5148700000000000,0.0051487,0.0002 +orml_xtokens,transfer_with_fee,5498700000000000,0.0054987,0.0002 +orml_xtokens,transfer_multiasset_with_fee,5288700000000000,0.0052887,0.0002 +orml_xtokens,transfer_multicurrencies,5718700000000000,0.0057187,0.0002 +orml_xtokens,transfer_multiassets,5198700000000000,0.0051987,0.0002 +manta_collator_selection,set_invulnerables,5299845518220000,0.00529984551822,0.0002 +manta_collator_selection,set_desired_candidates,5009860390000000,0.00500986039,0.0002 +manta_collator_selection,set_candidacy_bond,5129841580000000,0.00512984158,0.0002 +manta_collator_selection,register_as_candidate,4971566536980000,0.00497156653698,0.0002 +manta_collator_selection,register_candidate,5291582199940000,0.00529158219994,0.0002 +manta_collator_selection,leave_intent,4970396739710000,0.00497039673971,0.0002 +manta_collator_selection,remove_collator,5290671925700000,0.0052906719257,0.0002 +manta_collator_selection,set_eviction_baseline,4979835900000000,0.0049798359,0.0002 +manta_collator_selection,set_eviction_tolerance,4979973540000000,0.00497997354,0.0002 +pallet_asset_manager,register_asset,5316307190000000,0.00531630719,0.0002 +pallet_asset_manager,update_asset_location,5015632340000000,0.00501563234,0.0002 +pallet_asset_manager,update_asset_metadata,5442350760000000,0.00544235076,0.0002 +pallet_asset_manager,set_units_per_second,4990541800000000,0.0049905418,0.0002 +pallet_asset_manager,mint_asset,5462457200000000,0.0054624572,0.0002 +pallet_asset_manager,set_min_xcm_fee,5010191960000000,0.00501019196,0.0002 +pallet_asset_manager,update_outgoing_filtered_assets,5010187800000000,0.0050101878,0.0002 +pallet_asset_manager,register_lp_asset,5606858690000000,0.00560685869,0.0002 +pallet_asset_manager,permissionless_register_asset,5166885130000000,0.00516688513,0.0002 +pallet_assets,create,5620165880000000,0.00562016588,0.0002 +pallet_assets,force_create,5480154500000000,0.0054801545,0.0002 +pallet_assets,start_destroy,5130171810000000,0.00513017181,0.0002 +pallet_assets,destroy_accounts,7791438620000000,0.00779143862,0.0002 +pallet_assets,destroy_approvals,6460804100000000,0.0064608041,0.0002 +pallet_assets,finish_destroy,5130649260000000,0.00513064926,0.0002 +pallet_assets,mint,5471553610000000,0.00547155361,0.0002 +pallet_assets,burn,5471676020000000,0.00547167602,0.0002 +pallet_assets,transfer,5474260460000000,0.00547426046,0.0002 +pallet_assets,transfer_keep_alive,5474217320000000,0.00547421732,0.0002 +pallet_assets,force_transfer,5804289630000000,0.00580428963,0.0002 +pallet_assets,freeze,5460459300000000,0.0054604593,0.0002 +pallet_assets,thaw,5460471790000000,0.00546047179,0.0002 +pallet_assets,freeze_asset,5130166020000000,0.00513016602,0.0002 +pallet_assets,thaw_asset,5130168120000000,0.00513016812,0.0002 +pallet_assets,transfer_ownership,5460444430000000,0.00546044443,0.0002 +pallet_assets,set_team,6120165190000000,0.00612016519,0.0002 +pallet_assets,set_metadata,5800465145370000,0.00580046514537,0.0002 +pallet_assets,clear_metadata,5130451280000000,0.00513045128,0.0002 +pallet_assets,force_set_metadata,5810443381150000,0.00581044338115,0.0002 +pallet_assets,force_clear_metadata,5130449960000000,0.00513044996,0.0002 +pallet_assets,force_asset_status,6480156990000000,0.00648015699,0.0002 +pallet_assets,approve_transfer,5471472360000000,0.00547147236,0.0002 +pallet_assets,cancel_approval,5461509230000000,0.00546150923,0.0002 +pallet_assets,force_cancel_approval,5791499060000000,0.00579149906,0.0002 +pallet_assets,transfer_approved,5805624710000000,0.00580562471,0.0002 +pallet_assets,touch,5131553610000000,0.00513155361,0.0002 +pallet_assets,refund,5141553610000000,0.00514155361,0.0002 +pallet_author_inherent,kick_off_authorship_validation,4970878960000000,0.00497087896,0.0002 +pallet_balances,transfer-1,5310440560000000,0.00531044056,0.0002 +pallet_balances,transfer-1000_000,5340440560000000,0.00534044056,0.0002 +pallet_balances,set_balance,5320244400000000,0.0053202444,0.0002 +pallet_balances,force_transfer,5641671250000000,0.00564167125,0.0002 +pallet_balances,transfer_keep_alive-1,5310309940000000,0.00531030994,0.0002 +pallet_balances,transfer_keep_alive-1000_000,5340309940000000,0.00534030994,0.0002 +pallet_balances,transfer_all,5310368540000000,0.00531036854,0.0002 +pallet_balances,force_unreserve,5460166990000000,0.00546016699,0.0002 +pallet_manta_pay,to_private,6724398890000000,0.00672439889,0.0002 +pallet_manta_pay,private_transfer,7045238020000000,0.00704523802,0.0002 +pallet_manta_pay,to_public,6861796130000000,0.00686179613,0.0002 +pallet_manta_pay,public_transfer,5772978680000000,0.00577297868,0.0002 +pallet_manta_sbt,to_private,6759968430000000,0.00675996843,0.0002 +pallet_manta_sbt,force_to_private,7087821710000000,0.00708782171,0.0002 +pallet_manta_sbt,reserve_sbt,4983246660000000,0.00498324666,0.0002 +pallet_manta_sbt,allowlist_evm_account,5212268910000000,0.00521226891,0.0002 +pallet_manta_sbt,set_next_sbt_id,5139860600000000,0.0051398606,0.0002 +pallet_manta_sbt,remove_allowlist_evm_account,5209884650000000,0.00520988465,0.0002 +pallet_manta_sbt,change_free_reserve_account,5300034690000000,0.00530003469,0.0002 +pallet_manta_sbt,force_mint_sbt_eth,7629585440000000,0.00762958544,0.0002 +pallet_manta_sbt,change_force_account,5299868250000000,0.00529986825,0.0002 +pallet_manta_sbt,mint_sbt_eth,7839986680000000,0.00783998668,0.0002 +pallet_manta_sbt,change_allowlist_account,5299867840000000,0.00529986784,0.0002 +pallet_manta_sbt,update_mint_info,5121189210000000,0.00512118921,0.0002 +pallet_manta_sbt,new_mint_info,5082155170000000,0.00508215517,0.0002 +pallet_parachain_staking,set_staking_expectations,5450169770000000,0.00545016977,0.0002 +pallet_parachain_staking,set_inflation,5090635330000000,0.00509063533,0.0002 +pallet_parachain_staking,set_parachain_bond_account,5290172410000000,0.00529017241,0.0002 +pallet_parachain_staking,set_parachain_bond_account,5290172410000000,0.00529017241,0.0002 +pallet_parachain_staking,set_parachain_bond_reserve_percent,4980163440000000,0.00498016344,0.0002 +pallet_parachain_staking,set_total_selected,4980176300000000,0.0049801763,0.0002 +pallet_parachain_staking,set_collator_commission,4980147930000000,0.00498014793,0.0002 +pallet_parachain_staking,set_blocks_per_round,4980928560000000,0.00498092856,0.0002 +pallet_parachain_staking,join_candidates,4998155510680000,0.00499815551068,0.0002 +pallet_parachain_staking,schedule_leave_candidates,4981590489840000,0.00498159048984,0.0002 +pallet_parachain_staking,execute_leave_candidates,5312653954580000,0.00531265395458,0.0002 +pallet_parachain_staking,cancel_leave_candidates,4981569748780000,0.00498156974878,0.0002 +pallet_parachain_staking,go_offline,4971524000000000,0.004971524,0.0002 +pallet_parachain_staking,go_offline,4971524000000000,0.004971524,0.0002 +pallet_parachain_staking,candidate_bond_more,4985497510000000,0.00498549751,0.0002 +pallet_parachain_staking,schedule_candidate_bond_less,5130235200000000,0.0051302352,0.0002 +pallet_parachain_staking,execute_candidate_bond_less,5295592620000000,0.00529559262,0.0002 +pallet_parachain_staking,cancel_candidate_bond_less,4970222140000000,0.00497022214,0.0002 +pallet_parachain_staking,delegate_1_2_3,5328290401240000,0.00532829040124,0.0002 +pallet_parachain_staking,delegate_1_25_3,5328356837890000,0.00532835683789,0.0002 +pallet_parachain_staking,delegate_1_2_100,5338457533210000,0.00533845753321,0.0002 +pallet_parachain_staking,schedule_leave_delegators,4971525980000000,0.00497152598,0.0002 +pallet_parachain_staking,execute_leave_delegators,5313589823450000,0.00531358982345,0.0002 +pallet_parachain_staking,cancel_leave_delegators,4971569610000000,0.00497156961,0.0002 +pallet_parachain_staking,schedule_revoke_delegation,5291527000000000,0.005291527,0.0002 +pallet_parachain_staking,delegator_bond_more,5308436310000000,0.00530843631,0.0002 +pallet_parachain_staking,schedule_delegator_bond_less,5301545530000000,0.00530154553,0.0002 +pallet_parachain_staking,execute_delegation_request,5619579090000000,0.00561957909,0.0002 +pallet_parachain_staking,cancel_delegation_request,5291591330000000,0.00529159133,0.0002 +pallet_scheduler,cancel,5051918176790000,0.00505191817679,0.0002 +pallet_scheduler,schedule,5130601273350000,0.00513060127335,0.0002 +pallet_scheduler,schedule_named,5531911598540000,0.00553191159854,0.0002 +pallet_scheduler,cancel_named,5292194459230000,0.00529219445923,0.0002 +pallet_scheduler,schedule_after,5370601273350000,0.00537060127335,0.0002 +pallet_scheduler,schedule_named_after,5771911598540000,0.00577191159854,0.0002 +pallet_session,set_keys,5942729070000000,0.00594272907,0.0002 +pallet_session,purge_keys,4972173290000000,0.00497217329,0.0002 +pallet_tx_pause,pause_transaction,5630152180000000,0.00563015218,0.0002 +pallet_tx_pause,unpause_transaction,5630167150000000,0.00563016715,0.0002 +pallet_tx_pause,pause_transactions,5981604360000000,0.00598160436,0.0002 +pallet_tx_pause,unpause_transactions,5981634300000000,0.0059816343,0.0002 +pallet_tx_pause,pause_pallets,5711309000000000,0.005711309,0.0002 +pallet_tx_pause,unpause_pallets,5711309000000000,0.005711309,0.0002 +pallet_utility,batch-size=1,5009447130520000,0.00500944713052,0.0002 +pallet_utility,batch-size=32,5951821389360000,0.00595182138936,0.0002 +pallet_utility,as_derivative,5993143069360000,0.00599314306936,0.0002 +pallet_utility,batch_all-size=1,5009455785630000,0.00500945578563,0.0002 +pallet_utility,batch_all-size=32,5952098352880000,0.00595209835288,0.0002 +pallet_utility,dispatch_as,6312251342880000,0.00631225134288,0.0002 +pallet_utility,force_batch,4979043625280000,0.00497904362528,0.0002 +pallet_randomness,set_babe_randomness_results,4972600220000000,0.00497260022,0.0002 +pallet_name_service,register,5341969540000000,0.00534196954,0.0002 +pallet_name_service,accept_register,5341226430000000,0.00534122643,0.0002 +pallet_name_service,set_primary_name,5340479230000000,0.00534047923,0.0002 +pallet_name_service,cancel_pending_register,5340203160000000,0.00534020316,0.0002 +pallet_name_service,remove_register,5340479160000000,0.00534047916,0.0002 +pallet_farming,create_farming_pool,6123710100000000,0.0061237101,0.0002 +pallet_farming,charge,5785634250000000,0.00578563425,0.0002 +pallet_farming,deposit,5366946200000000,0.0053669462,0.0002 +pallet_farming,withdraw,5301602580000000,0.00530160258,0.0002 +pallet_farming,claim,5131858760000000,0.00513185876,0.0002 +pallet_farming,withdraw_claim,5131858760000000,0.00513185876,0.0002 +pallet_farming,close_pool,5128700010000000,0.00512870001,0.0002 +pallet_farming,set_retire_limit,5008700010000000,0.00500870001,0.0002 +pallet_farming,retire_pool,5128700010000000,0.00512870001,0.0002 +pallet_farming,reset_pool,6138700010000000,0.00613870001,0.0002 +pallet_farming,kill_pool,5128700010000000,0.00512870001,0.0002 +pallet_farming,edit_pool,6568700010000000,0.00656870001,0.0002 +pallet_farming,gauge_withdraw,5132146160000000,0.00513214616,0.0002 +pallet_farming,force_gauge_claim,5128700010000000,0.00512870001,0.0002 +pallet_lottery,deposit,5149392860640000,0.00514939286064,0.0002 +pallet_lottery,request_withdraw,5142131693200000,0.0051421316932,0.0002 +pallet_lottery,claim_my_winnings,4974532813190000,0.00497453281319,0.0002 +pallet_lottery,rebalance_stake,4968700000000000,0.0049687,0.0002 +pallet_lottery,start_lottery,4972949880000000,0.00497294988,0.0002 +pallet_lottery,stop_lottery,4971537340000000,0.00497153734,0.0002 +pallet_lottery,draw_lottery,4974822260000000,0.00497482226,0.0002 +pallet_lottery,process_matured_withdrawals,4969856860000000,0.00496985686,0.0002 +pallet_lottery,liquidate_lottery,4968700000000000,0.0049687,0.0002 +pallet_lottery,set_min_deposit,5130036700000000,0.0051300367,0.0002 +pallet_lottery,set_min_withdraw,5129745420000000,0.00512974542,0.0002 +pallet_lottery,set_gas_reserve,5129745510000000,0.00512974551,0.0002 +zenlink_protocol,set_fee_receiver,5300032150000000,0.00530003215,0.0002 +zenlink_protocol,set_fee_point,4980026310000000,0.00498002631,0.0002 +zenlink_protocol,transfer,5428710000000000,0.00542871,0.0002 +zenlink_protocol,transfer,5231771630000000,0.00523177163,0.0002 +zenlink_protocol,add_liquidity,5316404550000000,0.00531640455,0.0002 +zenlink_protocol,remove_liquidity,5609241100000000,0.0056092411,0.0002 +zenlink_protocol,swap_exact_assets_for_assets,5727991860000000,0.00572799186,0.0002 +zenlink_protocol,swap_assets_for_exact_assets,5727992870000000,0.00572799287,0.0002 +zenlink_protocol,bootstrap_create,6222208840000000,0.00622220884,0.0002 +zenlink_protocol,bootstrap_contribute,5287398280000000,0.00528739828,0.0002 +zenlink_protocol,bootstrap_claim,5587287890000000,0.00558728789,0.0002 +zenlink_protocol,bootstrap_end,5268945340000000,0.00526894534,0.0002 +zenlink_protocol,bootstrap_update,6232524390000000,0.00623252439,0.0002 +zenlink_protocol,bootstrap_refund,5237140050000000,0.00523714005,0.0002 +zenlink_protocol,bootstrap_charge_reward,5819700000000000,0.0058197,0.0002 +zenlink_protocol,bootstrap_withdraw_reward,5549700000000000,0.0055497,0.0002 +pallet_native_barrier,initialize_native_barrier,4979846780000000,0.00497984678,0.0002 +pallet_native_barrier,add_accounts_to_native_barrier,4985465700000000,0.0049854657,0.0002 +pallet_native_barrier,remove_accounts_from_native_barrier,4983893360000000,0.00498389336,0.0002 +frame_system,remark-length=32,5430846460000000,0.00543084646,0.2 +frame_system,remark-length=64,5430846460000000,0.00543084646,0.2 +frame_system,set_heap_pages,7383150000000000,0.00738315,0.2 +frame_system,set_code,5005298700000000000,5.0052987,0.2 +frame_system,set_code_without_checks,5005298700000000000,5.0052987,0.2 +frame_system,set_storage,6685697510000000,0.00668569751,0.2 +frame_system,kill_storage,7689164760000000,0.00768916476,0.2 +frame_system,kill_prefix,14500273090000000,0.01450027309,0.2 +frame_system,remark_with_event-length=32,5434565040000000,0.00543456504,0.2 +frame_system,remark_with_event-length=64,5434565040000000,0.00543456504,0.2 +pallet_treasury,propose_spend,7889570000000000,0.00788957,0.2 +pallet_treasury,reject_proposal,8020730000000000,0.00802073,0.2 +pallet_treasury,approve_proposal,6738014970000000,0.00673801497,0.2 +pallet_treasury,spend,5310410000000000,0.00531041,0.2 +pallet_treasury,remove_approval,6334130000000000,0.00633413,0.2 +pallet_timestamp,set,6316530000000000,0.00631653,0.2 +pallet_preimage,note_preimage-length=32,7889492080000000,0.00788949208,0.2 +pallet_preimage,note_preimage-length=32,8220434160000000,0.00822043416,0.2 +pallet_preimage,unnote_preimage,7957970000000000,0.00795797,0.2 +pallet_preimage,request_preimage,6820410000000000,0.00682041,0.2 +pallet_preimage,unrequest_preimage,7818880000000000,0.00781888,0.2 +pallet_multisig,as_multi_threshold_1,9614664490000000,0.00961466449,0.2 +pallet_multisig,as_multi,8621404520000000,0.00862140452,0.2 +pallet_multisig,approve_as_multi,7562306370000000,0.00756230637,0.2 +pallet_multisig,cancel_as_multi,7355106670000000,0.00735510667,0.2 +pallet_membership,add_member,5798700000000000,0.0057987,0.2 +pallet_membership,remove_member,5798700000000000,0.0057987,0.2 +pallet_membership,swap_member,6128700000000000,0.0061287,0.2 +pallet_membership,reset_members,6118700000000000,0.0061187,0.2 +pallet_membership,change_key,5798700000000000,0.0057987,0.2 +pallet_membership,set_prime,5798700000000000,0.0057987,0.2 +pallet_membership,clear_prime,5468700000000000,0.0054687,0.2 +pallet_democracy,propose,9324850000000000,0.00932485,0.2 +pallet_democracy,second,6706550000000000,0.00670655,0.2 +pallet_democracy,vote,9558350000000000,0.00955835,0.2 +pallet_democracy,emergency_cancel,7757860000000000,0.00775786,0.2 +pallet_democracy,external_propose,6710610000000000,0.00671061,0.2 +pallet_democracy,external_propose_majority,6075300000000000,0.0060753,0.2 +pallet_democracy,external_propose_default,6071630000000000,0.00607163,0.2 +pallet_democracy,fast_track,9108490000000000,0.00910849,0.2 +pallet_democracy,veto_external,8112850000000000,0.00811285,0.2 +pallet_democracy,cancel_referendum,6132820000000000,0.00613282,0.2 +pallet_democracy,delegate,139869211750000000,0.13986921175,0.2 +pallet_democracy,undelegate,136637290710000000,0.13663729071,0.2 +pallet_democracy,clear_public_proposals,6025580000000000,0.00602558,0.2 +pallet_democracy,unlock,9527223210000000,0.00952722321,0.2 +pallet_democracy,remove_vote,7860770440000000,0.00786077044,0.2 +pallet_democracy,remove_other_vote,8189918650000000,0.00818991865,0.2 +pallet_democracy,blacklist,13498820000000000,0.01349882,0.2 +pallet_democracy,cancel_proposal,9491760000000000,0.00949176,0.2 +pallet_collective,set_members,142773807120000000,0.14277380712,0.2 +pallet_collective,execute,10041635810000000,0.01004163581,0.2 +pallet_collective,propose,10551516700000000,0.0105515167,0.2 +pallet_collective,vote,7228217400000000,0.0072282174,0.2 +pallet_collective,close,10296160860000000,0.01029616086,0.2 +pallet_collective,disapprove_proposal,8954546660000000,0.00895454666,0.2 +cumulus_pallet_xcmp_queue,service_overweight,5138700640000000,0.00513870064,0.2 +cumulus_pallet_xcmp_queue,suspend_xcm_execution,5968700000000000,0.0059687,0.2 +cumulus_pallet_xcmp_queue,resume_xcm_execution,5968700000000000,0.0059687,0.2 +cumulus_pallet_xcmp_queue,update_suspend_threshold,6333790000000000,0.00633379,0.2 +cumulus_pallet_xcmp_queue,update_drop_threshold,6333790000000000,0.00633379,0.2 +cumulus_pallet_xcmp_queue,update_resume_threshold,6333790000000000,0.00633379,0.2 +cumulus_pallet_xcmp_queue,update_threshold_weight,6470150000000000,0.00647015,0.2 +cumulus_pallet_xcmp_queue,update_weight_restrict_decay,6470150000000000,0.00647015,0.2 +cumulus_pallet_xcmp_queue,update_xcmp_max_individual_weight,6470150000000000,0.00647015,0.2 +orml_xtokens,transfer,5338700000000000,0.0053387,0.2 +orml_xtokens,transfer_multiasset,5148700000000000,0.0051487,0.2 +orml_xtokens,transfer_with_fee,5498700000000000,0.0054987,0.2 +orml_xtokens,transfer_multiasset_with_fee,5288700000000000,0.0052887,0.2 +orml_xtokens,transfer_multicurrencies,5718700000000000,0.0057187,0.2 +orml_xtokens,transfer_multiassets,5198700000000000,0.0051987,0.2 +manta_collator_selection,set_invulnerables,6444218220000000,0.00644421822,0.2 +manta_collator_selection,set_desired_candidates,6169090000000000,0.00616909,0.2 +manta_collator_selection,set_candidacy_bond,6270280000000000,0.00627028,0.2 +manta_collator_selection,register_as_candidate,7835236980000000,0.00783523698,0.2 +manta_collator_selection,register_candidate,8170899940000000,0.00817089994,0.2 +manta_collator_selection,leave_intent,6665439710000000,0.00666543971,0.2 +manta_collator_selection,remove_collator,7260625700000000,0.0072606257,0.2 +manta_collator_selection,set_eviction_baseline,6114600000000000,0.0061146,0.2 +manta_collator_selection,set_eviction_tolerance,6252240000000000,0.00625224,0.2 +pallet_asset_manager,register_asset,12915890000000000,0.01291589,0.2 +pallet_asset_manager,update_asset_location,11941040000000000,0.01194104,0.2 +pallet_asset_manager,update_asset_metadata,9089460000000000,0.00908946,0.2 +pallet_asset_manager,set_units_per_second,6830500000000000,0.0068305,0.2 +pallet_asset_manager,mint_asset,9215900000000000,0.0092159,0.2 +pallet_asset_manager,set_min_xcm_fee,6500660000000000,0.00650066,0.2 +pallet_asset_manager,update_outgoing_filtered_assets,6496500000000000,0.0064965,0.2 +pallet_asset_manager,register_lp_asset,13757390000000000,0.01375739,0.2 +pallet_asset_manager,permissionless_register_asset,13343830000000000,0.01334383,0.2 +pallet_assets,create,7084580000000000,0.00708458,0.2 +pallet_assets,force_create,6933200000000000,0.0069332,0.2 +pallet_assets,start_destroy,6600510000000000,0.00660051,0.2 +pallet_assets,destroy_accounts,2667867320000000000,2.66786732,0.2 +pallet_assets,destroy_approvals,1337232800000000000,1.3372328,0.2 +pallet_assets,finish_destroy,7077960000000000,0.00707796,0.2 +pallet_assets,mint,8322310000000000,0.00832231,0.2 +pallet_assets,burn,8444720000000000,0.00844472,0.2 +pallet_assets,transfer,11029160000000000,0.01102916,0.2 +pallet_assets,transfer_keep_alive,10986020000000000,0.01098602,0.2 +pallet_assets,force_transfer,11388330000000000,0.01138833,0.2 +pallet_assets,freeze,7218000000000000,0.007218,0.2 +pallet_assets,thaw,7230490000000000,0.00723049,0.2 +pallet_assets,freeze_asset,6594720000000000,0.00659472,0.2 +pallet_assets,thaw_asset,6596820000000000,0.00659682,0.2 +pallet_assets,transfer_ownership,7203130000000000,0.00720313,0.2 +pallet_assets,set_team,7583890000000000,0.00758389,0.2 +pallet_assets,set_metadata,7563845370000000,0.00756384537,0.2 +pallet_assets,clear_metadata,6879980000000000,0.00687998,0.2 +pallet_assets,force_set_metadata,7552081150000000,0.00755208115,0.2 +pallet_assets,force_clear_metadata,6878660000000000,0.00687866,0.2 +pallet_assets,force_asset_status,7935690000000000,0.00793569,0.2 +pallet_assets,approve_transfer,8241060000000000,0.00824106,0.2 +pallet_assets,cancel_approval,8267930000000000,0.00826793,0.2 +pallet_assets,force_cancel_approval,8587760000000000,0.00858776,0.2 +pallet_assets,transfer_approved,12723410000000000,0.01272341,0.2 +pallet_assets,touch,7982310000000000,0.00798231,0.2 +pallet_assets,refund,7992310000000000,0.00799231,0.2 +pallet_author_inherent,kick_off_authorship_validation,7147660000000000,0.00714766,0.2 +pallet_balances,transfer-1,7049260000000000,0.00704926,0.2 +pallet_balances,transfer-1000_000,7079260000000000,0.00707926,0.2 +pallet_balances,set_balance,6863100000000000,0.0068631,0.2 +pallet_balances,force_transfer,8609950000000000,0.00860995,0.2 +pallet_balances,transfer_keep_alive-1,6918640000000000,0.00691864,0.2 +pallet_balances,transfer_keep_alive-1000_000,6948640000000000,0.00694864,0.2 +pallet_balances,transfer_all,6977240000000000,0.00697724,0.2 +pallet_balances,force_unreserve,6925690000000000,0.00692569,0.2 +pallet_manta_pay,to_private,412017590000000000,0.41201759,0.2 +pallet_manta_pay,private_transfer,732856720000000000,0.73285672,0.2 +pallet_manta_pay,to_public,549414830000000000,0.54941483,0.2 +pallet_manta_pay,public_transfer,10047380000000000,0.01004738,0.2 +pallet_manta_sbt,to_private,407627130000000000,0.40762713,0.2 +pallet_manta_sbt,force_to_private,405810410000000000,0.40581041,0.2 +pallet_manta_sbt,reserve_sbt,9525360000000000,0.00952536,0.2 +pallet_manta_sbt,allowlist_evm_account,8777610000000000,0.00877761,0.2 +pallet_manta_sbt,set_next_sbt_id,6299300000000000,0.0062993,0.2 +pallet_manta_sbt,remove_allowlist_evm_account,6393350000000000,0.00639335,0.2 +pallet_manta_sbt,change_free_reserve_account,6633390000000000,0.00663339,0.2 +pallet_manta_sbt,force_mint_sbt_eth,408114140000000000,0.40811414,0.2 +pallet_manta_sbt,change_force_account,6466950000000000,0.00646695,0.2 +pallet_manta_sbt,mint_sbt_eth,408725380000000000,0.40872538,0.2 +pallet_manta_sbt,change_allowlist_account,6466540000000000,0.00646654,0.2 +pallet_manta_sbt,update_mint_info,7607910000000000,0.00760791,0.2 +pallet_manta_sbt,new_mint_info,8533870000000000,0.00853387,0.2 +pallet_parachain_staking,set_staking_expectations,6918470000000000,0.00691847,0.2 +pallet_parachain_staking,set_inflation,7024030000000000,0.00702403,0.2 +pallet_parachain_staking,set_parachain_bond_account,6761110000000000,0.00676111,0.2 +pallet_parachain_staking,set_parachain_bond_account,6761110000000000,0.00676111,0.2 +pallet_parachain_staking,set_parachain_bond_reserve_percent,6442140000000000,0.00644214,0.2 +pallet_parachain_staking,set_total_selected,6455000000000000,0.006455,0.2 +pallet_parachain_staking,set_collator_commission,6426630000000000,0.00642663,0.2 +pallet_parachain_staking,set_blocks_per_round,7207260000000000,0.00720726,0.2 +pallet_parachain_staking,join_candidates,14444210680000000,0.01444421068,0.2 +pallet_parachain_staking,schedule_leave_candidates,7869189840000000,0.00786918984,0.2 +pallet_parachain_staking,execute_leave_candidates,19252654580000000,0.01925265458,0.2 +pallet_parachain_staking,cancel_leave_candidates,7848448780000000,0.00784844878,0.2 +pallet_parachain_staking,go_offline,7792700000000000,0.0077927,0.2 +pallet_parachain_staking,go_offline,7792700000000000,0.0077927,0.2 +pallet_parachain_staking,candidate_bond_more,11776210000000000,0.01177621,0.2 +pallet_parachain_staking,schedule_candidate_bond_less,6663900000000000,0.0066639,0.2 +pallet_parachain_staking,execute_candidate_bond_less,12181320000000000,0.01218132,0.2 +pallet_parachain_staking,cancel_candidate_bond_less,6490840000000000,0.00649084,0.2 +pallet_parachain_staking,delegate_1_2_3,14909101240000000,0.01490910124,0.2 +pallet_parachain_staking,delegate_1_25_3,14975537890000000,0.01497553789,0.2 +pallet_parachain_staking,delegate_1_2_100,15086233210000000,0.01508623321,0.2 +pallet_parachain_staking,schedule_leave_delegators,7794680000000000,0.00779468,0.2 +pallet_parachain_staking,execute_leave_delegators,20188523450000000,0.02018852345,0.2 +pallet_parachain_staking,cancel_leave_delegators,7838310000000000,0.00783831,0.2 +pallet_parachain_staking,schedule_revoke_delegation,8115700000000000,0.0081157,0.2 +pallet_parachain_staking,delegator_bond_more,15035010000000000,0.01503501,0.2 +pallet_parachain_staking,schedule_delegator_bond_less,8144230000000000,0.00814423,0.2 +pallet_parachain_staking,execute_delegation_request,16487790000000000,0.01648779,0.2 +pallet_parachain_staking,cancel_delegation_request,8180030000000000,0.00818003,0.2 +pallet_scheduler,cancel,8266876790000000,0.00826687679,0.2 +pallet_scheduler,schedule,7029973350000000,0.00702997335,0.2 +pallet_scheduler,schedule_named,8740298540000000,0.00874029854,0.2 +pallet_scheduler,cancel_named,8783159230000000,0.00878315923,0.2 +pallet_scheduler,schedule_after,7269973350000000,0.00726997335,0.2 +pallet_scheduler,schedule_named_after,8980298540000000,0.00898029854,0.2 +pallet_session,set_keys,9967770000000000,0.00996777,0.2 +pallet_session,purge_keys,8441990000000000,0.00844199,0.2 +pallet_tx_pause,pause_transaction,7080880000000000,0.00708088,0.2 +pallet_tx_pause,unpause_transaction,7095850000000000,0.00709585,0.2 +pallet_tx_pause,pause_transactions,8883060000000000,0.00888306,0.2 +pallet_tx_pause,unpause_transactions,8913000000000000,0.008913,0.2 +pallet_tx_pause,pause_pallets,78247700000000000,0.0782477,0.2 +pallet_tx_pause,unpause_pallets,78247700000000000,0.0782477,0.2 +pallet_utility,batch-size=1,5755830520000000,0.00575583052,0.2 +pallet_utility,batch-size=32,19060089360000000,0.01906008936,0.2 +pallet_utility,as_derivative,20421769360000000,0.02042176936,0.2 +pallet_utility,batch_all-size=1,5764485630000000,0.00576448563,0.2 +pallet_utility,batch_all-size=32,19337052880000000,0.01933705288,0.2 +pallet_utility,dispatch_as,19850042880000000,0.01985004288,0.2 +pallet_utility,force_batch,5322325280000000,0.00532232528,0.2 +pallet_randomness,set_babe_randomness_results,8868920000000000,0.00886892,0.2 +pallet_name_service,register,8608240000000000,0.00860824,0.2 +pallet_name_service,accept_register,7865130000000000,0.00786513,0.2 +pallet_name_service,set_primary_name,7117930000000000,0.00711793,0.2 +pallet_name_service,cancel_pending_register,6841860000000000,0.00684186,0.2 +pallet_name_service,remove_register,7117860000000000,0.00711786,0.2 +pallet_farming,create_farming_pool,11128800000000000,0.0111288,0.2 +pallet_farming,charge,12712950000000000,0.01271295,0.2 +pallet_farming,deposit,13604900000000000,0.0136049,0.2 +pallet_farming,withdraw,8201280000000000,0.00820128,0.2 +pallet_farming,claim,8287460000000000,0.00828746,0.2 +pallet_farming,withdraw_claim,8287460000000000,0.00828746,0.2 +pallet_farming,close_pool,5128710000000000,0.00512871,0.2 +pallet_farming,set_retire_limit,5008710000000000,0.00500871,0.2 +pallet_farming,retire_pool,5128710000000000,0.00512871,0.2 +pallet_farming,reset_pool,6138710000000000,0.00613871,0.2 +pallet_farming,kill_pool,5128710000000000,0.00512871,0.2 +pallet_farming,edit_pool,6568710000000000,0.00656871,0.2 +pallet_farming,gauge_withdraw,8574860000000000,0.00857486,0.2 +pallet_farming,force_gauge_claim,5128710000000000,0.00512871,0.2 +pallet_lottery,deposit,25821560640000000,0.02582156064,0.2 +pallet_lottery,request_withdraw,18560393200000000,0.0185603932,0.2 +pallet_lottery,claim_my_winnings,10801513190000000,0.01080151319,0.2 +pallet_lottery,rebalance_stake,4968700000000000,0.0049687,0.2 +pallet_lottery,start_lottery,9218580000000000,0.00921858,0.2 +pallet_lottery,stop_lottery,7806040000000000,0.00780604,0.2 +pallet_lottery,draw_lottery,11090960000000000,0.01109096,0.2 +pallet_lottery,process_matured_withdrawals,6125560000000000,0.00612556,0.2 +pallet_lottery,liquidate_lottery,4968700000000000,0.0049687,0.2 +pallet_lottery,set_min_deposit,6465400000000000,0.0064654,0.2 +pallet_lottery,set_min_withdraw,6174120000000000,0.00617412,0.2 +pallet_lottery,set_gas_reserve,6174210000000000,0.00617421,0.2 +zenlink_protocol,set_fee_receiver,6630850000000000,0.00663085,0.2 +zenlink_protocol,set_fee_point,6305010000000000,0.00630501,0.2 +zenlink_protocol,transfer,5438700000000000,0.0054387,0.2 +zenlink_protocol,transfer,8300330000000000,0.00830033,0.2 +zenlink_protocol,add_liquidity,42983250000000000,0.04298325,0.2 +zenlink_protocol,remove_liquidity,26129800000000000,0.0261298,0.2 +zenlink_protocol,swap_exact_assets_for_assets,15010560000000000,0.01501056,0.2 +zenlink_protocol,swap_assets_for_exact_assets,15011570000000000,0.01501157,0.2 +zenlink_protocol,bootstrap_create,9727540000000000,0.00972754,0.2 +zenlink_protocol,bootstrap_contribute,13976980000000000,0.01397698,0.2 +zenlink_protocol,bootstrap_claim,34146590000000000,0.03414659,0.2 +zenlink_protocol,bootstrap_end,45474040000000000,0.04547404,0.2 +zenlink_protocol,bootstrap_update,10053090000000000,0.01005309,0.2 +zenlink_protocol,bootstrap_refund,13668750000000000,0.01366875,0.2 +zenlink_protocol,bootstrap_charge_reward,6818700000000000,0.0068187,0.2 +zenlink_protocol,bootstrap_withdraw_reward,6548700000000000,0.0065487,0.2 +pallet_native_barrier,initialize_native_barrier,6125480000000000,0.00612548,0.2 +pallet_native_barrier,add_accounts_to_native_barrier,11744400000000000,0.0117444,0.2 +pallet_native_barrier,remove_accounts_from_native_barrier,10172060000000000,0.01017206,0.2 +frame_system,remark-length=32,5959432300000000,0.0059594323,1 +frame_system,remark-length=64,5959432300000000,0.0059594323,1 +frame_system,set_heap_pages,16720950000000000,0.01672095,1 +frame_system,set_code,25005298700000000000,25.0052987,1 +frame_system,set_code_without_checks,25005298700000000000,25.0052987,1 +frame_system,set_storage,10873687550000000,0.01087368755,1 +frame_system,kill_storage,15891023800000000,0.0158910238,1 +frame_system,kill_prefix,51146565450000000,0.05114656545,1 +frame_system,remark_with_event-length=32,5978025200000000,0.0059780252,1 +frame_system,remark_with_event-length=64,5978025200000000,0.0059780252,1 +pallet_treasury,propose_spend,18213050000000000,0.01821305,1 +pallet_treasury,reject_proposal,20188850000000000,0.02018885,1 +pallet_treasury,approve_proposal,13775274850000000,0.01377527485,1 +pallet_treasury,spend,5317250000000000,0.00531725,1 +pallet_treasury,remove_approval,11755850000000000,0.01175585,1 +pallet_timestamp,set,11667850000000000,0.01166785,1 +pallet_preimage,note_preimage-length=32,18252660400000000,0.0182526604,1 +pallet_preimage,note_preimage-length=32,18587370800000000,0.0185873708,1 +pallet_preimage,unnote_preimage,18635050000000000,0.01863505,1 +pallet_preimage,request_preimage,12947250000000000,0.01294725,1 +pallet_preimage,unrequest_preimage,17939600000000000,0.0179396,1 +pallet_multisig,as_multi_threshold_1,25518522450000000,0.02551852245,1 +pallet_multisig,as_multi,20352222600000000,0.0203522226,1 +pallet_multisig,approve_as_multi,15136731850000000,0.01513673185,1 +pallet_multisig,cancel_as_multi,13900733350000000,0.01390073335,1 +pallet_membership,add_member,7798700000000000,0.0077987,1 +pallet_membership,remove_member,7798700000000000,0.0077987,1 +pallet_membership,swap_member,8128700000000000,0.0081287,1 +pallet_membership,reset_members,8118700000000000,0.0081187,1 +pallet_membership,change_key,7798700000000000,0.0077987,1 +pallet_membership,set_prime,7798700000000000,0.0077987,1 +pallet_membership,clear_prime,7468700000000000,0.0074687,1 +pallet_democracy,propose,26509450000000000,0.02650945,1 +pallet_democracy,second,13617950000000000,0.01361795,1 +pallet_democracy,vote,27156950000000000,0.02715695,1 +pallet_democracy,emergency_cancel,18754500000000000,0.0187545,1 +pallet_democracy,external_propose,13478250000000000,0.01347825,1 +pallet_democracy,external_propose_majority,10301700000000000,0.0103017,1 +pallet_democracy,external_propose_default,10283350000000000,0.01028335,1 +pallet_democracy,fast_track,24067650000000000,0.02406765,1 +pallet_democracy,veto_external,19409450000000000,0.01940945,1 +pallet_democracy,cancel_referendum,10749300000000000,0.0107493,1 +pallet_democracy,delegate,677471258750000000,0.67747125875,1 +pallet_democracy,undelegate,663311653550000000,0.66331165355,1 +pallet_democracy,clear_public_proposals,10253100000000000,0.0102531,1 +pallet_democracy,unlock,26441316050000000,0.02644131605,1 +pallet_democracy,remove_vote,19269052200000000,0.0192690522,1 +pallet_democracy,remove_other_vote,19594793250000000,0.01959479325,1 +pallet_democracy,blacklist,46139300000000000,0.0461393,1 +pallet_democracy,cancel_proposal,27544000000000000,0.027544,1 +pallet_collective,set_members,689914235600000000,0.6899142356,1 +pallet_collective,execute,30173379050000000,0.03017337905,1 +pallet_collective,propose,32682783500000000,0.0326827835,1 +pallet_collective,vote,14906287000000000,0.014906287,1 +pallet_collective,close,30166004300000000,0.0301660043,1 +pallet_collective,disapprove_proposal,23617933300000000,0.0236179333,1 +cumulus_pallet_xcmp_queue,service_overweight,5178703200000000,0.0051787032,1 +cumulus_pallet_xcmp_queue,suspend_xcm_execution,9968700000000000,0.0099687,1 +cumulus_pallet_xcmp_queue,resume_xcm_execution,9968700000000000,0.0099687,1 +cumulus_pallet_xcmp_queue,update_suspend_threshold,11634150000000000,0.01163415,1 +cumulus_pallet_xcmp_queue,update_drop_threshold,11634150000000000,0.01163415,1 +cumulus_pallet_xcmp_queue,update_resume_threshold,11634150000000000,0.01163415,1 +cumulus_pallet_xcmp_queue,update_threshold_weight,12155950000000000,0.01215595,1 +cumulus_pallet_xcmp_queue,update_weight_restrict_decay,12155950000000000,0.01215595,1 +cumulus_pallet_xcmp_queue,update_xcmp_max_individual_weight,12155950000000000,0.01215595,1 +orml_xtokens,transfer,5338700000000000,0.0053387,1 +orml_xtokens,transfer_multiasset,5148700000000000,0.0051487,1 +orml_xtokens,transfer_with_fee,5498700000000000,0.0054987,1 +orml_xtokens,transfer_multiasset_with_fee,5288700000000000,0.0052887,1 +orml_xtokens,transfer_multicurrencies,5718700000000000,0.0057187,1 +orml_xtokens,transfer_multiassets,5198700000000000,0.0051987,1 +manta_collator_selection,set_invulnerables,11026291100000000,0.0110262911,1 +manta_collator_selection,set_desired_candidates,10810650000000000,0.01081065,1 +manta_collator_selection,set_candidacy_bond,10836600000000000,0.0108366,1 +manta_collator_selection,register_as_candidate,19301384900000000,0.0193013849,1 +manta_collator_selection,register_candidate,19699699700000000,0.0196996997,1 +manta_collator_selection,leave_intent,13452398550000000,0.01345239855,1 +manta_collator_selection,remove_collator,15148328500000000,0.0151483285,1 +manta_collator_selection,set_eviction_baseline,10658200000000000,0.0106582,1 +manta_collator_selection,set_eviction_tolerance,11346400000000000,0.0113464,1 +pallet_asset_manager,register_asset,43344650000000000,0.04334465,1 +pallet_asset_manager,update_asset_location,39670400000000000,0.0396704,1 +pallet_asset_manager,update_asset_metadata,23692500000000000,0.0236925,1 +pallet_asset_manager,set_units_per_second,14197700000000000,0.0141977,1 +pallet_asset_manager,mint_asset,24244700000000000,0.0242447,1 +pallet_asset_manager,set_min_xcm_fee,12468500000000000,0.0124685,1 +pallet_asset_manager,update_outgoing_filtered_assets,12447700000000000,0.0124477,1 +pallet_asset_manager,register_lp_asset,46392150000000000,0.04639215,1 +pallet_asset_manager,permissionless_register_asset,46084350000000000,0.04608435,1 +pallet_assets,create,12948100000000000,0.0129481,1 +pallet_assets,force_create,12751200000000000,0.0127512,1 +pallet_assets,start_destroy,12487750000000000,0.01248775,1 +pallet_assets,destroy_accounts,13318821800000000000,13.3188218,1 +pallet_assets,destroy_approvals,6665649200000000000,6.6656492,1 +pallet_assets,finish_destroy,14875000000000000,0.014875,1 +pallet_assets,mint,19736750000000000,0.01973675,1 +pallet_assets,burn,20348800000000000,0.0203488,1 +pallet_assets,transfer,33271000000000000,0.033271,1 +pallet_assets,transfer_keep_alive,33055300000000000,0.0330553,1 +pallet_assets,force_transfer,33746850000000000,0.03374685,1 +pallet_assets,freeze,14255200000000000,0.0142552,1 +pallet_assets,thaw,14317650000000000,0.01431765,1 +pallet_assets,freeze_asset,12458800000000000,0.0124588,1 +pallet_assets,thaw_asset,12469300000000000,0.0124693,1 +pallet_assets,transfer_ownership,14180850000000000,0.01418085,1 +pallet_assets,set_team,13444650000000000,0.01344465,1 +pallet_assets,set_metadata,14624426850000000,0.01462442685,1 +pallet_assets,clear_metadata,13885100000000000,0.0138851,1 +pallet_assets,force_set_metadata,14525605750000000,0.01452560575,1 +pallet_assets,force_clear_metadata,13878500000000000,0.0138785,1 +pallet_assets,force_asset_status,13763650000000000,0.01376365,1 +pallet_assets,approve_transfer,19330500000000000,0.0193305,1 +pallet_assets,cancel_approval,19504850000000000,0.01950485,1 +pallet_assets,force_cancel_approval,19784000000000000,0.019784,1 +pallet_assets,transfer_approved,40422250000000000,0.04042225,1 +pallet_assets,touch,19396750000000000,0.01939675,1 +pallet_assets,refund,19406750000000000,0.01940675,1 +pallet_author_inherent,kick_off_authorship_validation,15863500000000000,0.0158635,1 +pallet_balances,transfer-1,14011500000000000,0.0140115,1 +pallet_balances,transfer-1000_000,14041500000000000,0.0140415,1 +pallet_balances,set_balance,13040700000000000,0.0130407,1 +pallet_balances,force_transfer,20494950000000000,0.02049495,1 +pallet_balances,transfer_keep_alive-1,13358400000000000,0.0133584,1 +pallet_balances,transfer_keep_alive-1000_000,13388400000000000,0.0133884,1 +pallet_balances,transfer_all,13651400000000000,0.0136514,1 +pallet_balances,force_unreserve,12793650000000000,0.01279365,1 +pallet_manta_pay,to_private,2034813150000000000,2.03481315,1 +pallet_manta_pay,private_transfer,3639008800000000000,3.6390088,1 +pallet_manta_pay,to_public,2721799350000000000,2.72179935,1 +pallet_manta_pay,public_transfer,27162100000000000,0.0271621,1 +pallet_manta_sbt,to_private,2012700850000000000,2.01270085,1 +pallet_manta_sbt,force_to_private,2002297250000000000,2.00229725,1 +pallet_manta_sbt,reserve_sbt,27712000000000000,0.027712,1 +pallet_manta_sbt,allowlist_evm_account,23053250000000000,0.02305325,1 +pallet_manta_sbt,set_next_sbt_id,10941700000000000,0.0109417,1 +pallet_manta_sbt,remove_allowlist_evm_account,11131950000000000,0.01113195,1 +pallet_manta_sbt,change_free_reserve_account,11972150000000000,0.01197215,1 +pallet_manta_sbt,force_mint_sbt_eth,2011655900000000000,2.0116559,1 +pallet_manta_sbt,change_force_account,11139950000000000,0.01113995,1 +pallet_manta_sbt,mint_sbt_eth,2013872100000000000,2.0138721,1 +pallet_manta_sbt,change_allowlist_account,11137900000000000,0.0111379,1 +pallet_manta_sbt,update_mint_info,17564750000000000,0.01756475,1 +pallet_manta_sbt,new_mint_info,22354550000000000,0.02235455,1 +pallet_parachain_staking,set_staking_expectations,12797550000000000,0.01279755,1 +pallet_parachain_staking,set_inflation,14765350000000000,0.01476535,1 +pallet_parachain_staking,set_parachain_bond_account,12650750000000000,0.01265075,1 +pallet_parachain_staking,set_parachain_bond_account,12650750000000000,0.01265075,1 +pallet_parachain_staking,set_parachain_bond_reserve_percent,12295900000000000,0.0122959,1 +pallet_parachain_staking,set_total_selected,12360200000000000,0.0123602,1 +pallet_parachain_staking,set_collator_commission,12218350000000000,0.01221835,1 +pallet_parachain_staking,set_blocks_per_round,16121500000000000,0.0161215,1 +pallet_parachain_staking,join_candidates,52266253400000000,0.0522662534,1 +pallet_parachain_staking,schedule_leave_candidates,19431149200000000,0.0194311492,1 +pallet_parachain_staking,execute_leave_candidates,75068472900000000,0.0750684729,1 +pallet_parachain_staking,cancel_leave_candidates,19327443900000000,0.0193274439,1 +pallet_parachain_staking,go_offline,19088700000000000,0.0190887,1 +pallet_parachain_staking,go_offline,19088700000000000,0.0190887,1 +pallet_parachain_staking,candidate_bond_more,38966250000000000,0.03896625,1 +pallet_parachain_staking,schedule_candidate_bond_less,12804700000000000,0.0128047,1 +pallet_parachain_staking,execute_candidate_bond_less,39751800000000000,0.0397518,1 +pallet_parachain_staking,cancel_candidate_bond_less,12579400000000000,0.0125794,1 +pallet_parachain_staking,delegate_1_2_3,53270706200000000,0.0532707062,1 +pallet_parachain_staking,delegate_1_25_3,53602889450000000,0.05360288945,1 +pallet_parachain_staking,delegate_1_2_100,54116366050000000,0.05411636605,1 +pallet_parachain_staking,schedule_leave_delegators,19098600000000000,0.0190986,1 +pallet_parachain_staking,execute_leave_delegators,79747817250000000,0.07974781725,1 +pallet_parachain_staking,cancel_leave_delegators,19316750000000000,0.01931675,1 +pallet_parachain_staking,schedule_revoke_delegation,19423700000000000,0.0194237,1 +pallet_parachain_staking,delegator_bond_more,53980250000000000,0.05398025,1 +pallet_parachain_staking,schedule_delegator_bond_less,19526350000000000,0.01952635,1 +pallet_parachain_staking,execute_delegation_request,60004150000000000,0.06000415,1 +pallet_parachain_staking,cancel_delegation_request,19745350000000000,0.01974535,1 +pallet_scheduler,cancel,21139583950000000,0.02113958395,1 +pallet_scheduler,schedule,14635066750000000,0.01463506675,1 +pallet_scheduler,schedule_named,21586692700000000,0.0215866927,1 +pallet_scheduler,cancel_named,22760996150000000,0.02276099615,1 +pallet_scheduler,schedule_after,14875066750000000,0.01487506675,1 +pallet_scheduler,schedule_named_after,21826692700000000,0.0218266927,1 +pallet_session,set_keys,26084050000000000,0.02608405,1 +pallet_session,purge_keys,22335150000000000,0.02233515,1 +pallet_tx_pause,pause_transaction,12889600000000000,0.0128896,1 +pallet_tx_pause,unpause_transaction,12964450000000000,0.01296445,1 +pallet_tx_pause,pause_transactions,20500500000000000,0.0205005,1 +pallet_tx_pause,unpause_transactions,20650200000000000,0.0206502,1 +pallet_tx_pause,pause_pallets,368683700000000000,0.3686837,1 +pallet_tx_pause,unpause_pallets,368683700000000000,0.3686837,1 +pallet_utility,batch-size=1,8744352600000000,0.0087443526,1 +pallet_utility,batch-size=32,71545646800000000,0.0715456468,1 +pallet_utility,as_derivative,78194046800000000,0.0781940468,1 +pallet_utility,batch_all-size=1,8787628150000000,0.00878762815,1 +pallet_utility,batch_all-size=32,72930464400000000,0.0729304644,1 +pallet_utility,dispatch_as,74055414400000000,0.0740554144,1 +pallet_utility,force_batch,6696826400000000,0.0066968264,1 +pallet_randomness,set_babe_randomness_results,24469800000000000,0.0244698,1 +pallet_name_service,register,21686400000000000,0.0216864,1 +pallet_name_service,accept_register,17970850000000000,0.01797085,1 +pallet_name_service,set_primary_name,14234850000000000,0.01423485,1 +pallet_name_service,cancel_pending_register,12854500000000000,0.0128545,1 +pallet_name_service,remove_register,14234500000000000,0.0142345,1 +pallet_farming,create_farming_pool,31169200000000000,0.0311692,1 +pallet_farming,charge,40449950000000000,0.04044995,1 +pallet_farming,deposit,46589700000000000,0.0465897,1 +pallet_farming,withdraw,19811600000000000,0.0198116,1 +pallet_farming,claim,20922500000000000,0.0209225,1 +pallet_farming,withdraw_claim,20922500000000000,0.0209225,1 +pallet_farming,close_pool,5128750000000000,0.00512875,1 +pallet_farming,set_retire_limit,5008750000000000,0.00500875,1 +pallet_farming,retire_pool,5128750000000000,0.00512875,1 +pallet_farming,reset_pool,6138750000000000,0.00613875,1 +pallet_farming,kill_pool,5128750000000000,0.00512875,1 +pallet_farming,edit_pool,6568750000000000,0.00656875,1 +pallet_farming,gauge_withdraw,22359500000000000,0.0223595,1 +pallet_farming,force_gauge_claim,5128750000000000,0.00512875,1 +pallet_lottery,deposit,108593003200000000,0.1085930032,1 +pallet_lottery,request_withdraw,72287166000000000,0.072287166,1 +pallet_lottery,claim_my_winnings,34132765950000000,0.03413276595,1 +pallet_lottery,rebalance_stake,4968700000000000,0.0049687,1 +pallet_lottery,start_lottery,26218100000000000,0.0262181,1 +pallet_lottery,stop_lottery,19155400000000000,0.0191554,1 +pallet_lottery,draw_lottery,35580000000000000,0.03558,1 +pallet_lottery,process_matured_withdrawals,10753000000000000,0.010753,1 +pallet_lottery,liquidate_lottery,4968700000000000,0.0049687,1 +pallet_lottery,set_min_deposit,11812200000000000,0.0118122,1 +pallet_lottery,set_min_withdraw,10355800000000000,0.0103558,1 +pallet_lottery,set_gas_reserve,10356250000000000,0.01035625,1 +zenlink_protocol,set_fee_receiver,11959450000000000,0.01195945,1 +zenlink_protocol,set_fee_point,11610250000000000,0.01161025,1 +zenlink_protocol,transfer,5478700000000000,0.0054787,1 +zenlink_protocol,transfer,20586850000000000,0.02058685,1 +zenlink_protocol,add_liquidity,193801450000000000,0.19380145,1 +zenlink_protocol,remove_liquidity,108294200000000000,0.1082942,1 +zenlink_protocol,swap_exact_assets_for_assets,52178000000000000,0.052178,1 +zenlink_protocol,swap_assets_for_exact_assets,52183050000000000,0.05218305,1 +zenlink_protocol,bootstrap_create,23762900000000000,0.0237629,1 +zenlink_protocol,bootstrap_contribute,48770100000000000,0.0487701,1 +zenlink_protocol,bootstrap_claim,148498150000000000,0.14849815,1 +zenlink_protocol,bootstrap_end,206455400000000000,0.2064554,1 +zenlink_protocol,bootstrap_update,25350650000000000,0.02535065,1 +zenlink_protocol,bootstrap_refund,47428950000000000,0.04742895,1 +zenlink_protocol,bootstrap_charge_reward,10818700000000000,0.0108187,1 +zenlink_protocol,bootstrap_withdraw_reward,10548700000000000,0.0105487,1 +pallet_native_barrier,initialize_native_barrier,10712600000000000,0.0107126,1 +pallet_native_barrier,add_accounts_to_native_barrier,38807200000000000,0.0388072,1 +pallet_native_barrier,remove_accounts_from_native_barrier,30945500000000000,0.0309455,1 From de34377f2898bd595941048cf0f70339dbab189a Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Tue, 29 Aug 2023 14:03:22 +0300 Subject: [PATCH 59/69] Udpate lastdayprocessed on init Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/lib.rs | 16 ++++++++++------ pallets/native-barrier/src/tests.rs | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 0f1fe0245..678583c6f 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -168,12 +168,13 @@ pub mod pallet { let days_since_start = (now.as_secs() - start_unix_time.as_secs()) / (24 * 60 * 60); - // Default 0 is ok, it would only be used the first time - let last_day_processed = >::get().unwrap_or(0); - - if days_since_start > last_day_processed || days_since_start == 0 { - Self::reset_remaining_limit(days_since_start - last_day_processed); - >::put(days_since_start); + if let Some(last_day_processed) = >::get() { + if days_since_start > last_day_processed { + Self::reset_remaining_limit(days_since_start - last_day_processed); + >::put(days_since_start); + } + } else { + >::put(0); } } } @@ -194,6 +195,9 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; >::set(init); + if >::get().is_none() { + >::put(0); + } Self::deposit_event(Event::NativeBarrierInitialized { init }); Ok(()) } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 6aa9619b9..83ce7593a 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -347,7 +347,7 @@ fn limits_should_grow_appropriately() { initialize_native_barrier(daily_limit, Duration::from_secs(advance_10)); loop_on_init_and_assert_accounts(Some(0)); - assert_eq!(NativeBarrier::get_last_day_processed(), None); + assert_eq!(NativeBarrier::get_last_day_processed(), Some(0)); // roll 20 days (10 days after start) advance_mock_time(Duration::from_secs(advance_10 * 2)); From b9a420ca701f75ebc93bbb8cfd18398522ed0704 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 30 Aug 2023 09:19:09 +0300 Subject: [PATCH 60/69] add accounts to initialize barrier extrinsic Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/benchmarking.rs | 20 ++++++++++++++++---- pallets/native-barrier/src/lib.rs | 11 +++++++++++ pallets/native-barrier/src/tests.rs | 11 ++++++++--- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 78123112b..0e4af1005 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -37,7 +37,11 @@ benchmarks! { on_initialize { let daily_limit = T::Balance::zero(); let start_unix_time = Duration::default(); - let _ = NativeBarrier::::initialize_native_barrier(RawOrigin::Root.into(), Some((daily_limit, start_unix_time)))?; + let _ = NativeBarrier::::initialize_native_barrier( + RawOrigin::Root.into(), + Some((daily_limit, start_unix_time)), + None + )?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -64,7 +68,7 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); let start_unix_time = Duration::default(); - }: initialize_native_barrier(RawOrigin::Root, Some((daily_limit, start_unix_time))) + }: initialize_native_barrier(RawOrigin::Root, Some((daily_limit, start_unix_time)), None) verify { assert_eq!(NativeBarrier::::get_configurations().unwrap(), (daily_limit, start_unix_time)); } @@ -75,7 +79,11 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); let start_unix_time = Duration::default(); - let _ = NativeBarrier::::initialize_native_barrier(RawOrigin::Root.into(), Some((daily_limit, start_unix_time)))?; + let _ = NativeBarrier::::initialize_native_barrier( + RawOrigin::Root.into(), + Some((daily_limit, start_unix_time)), + None + )?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), @@ -95,7 +103,11 @@ benchmarks! { remove_accounts_from_native_barrier { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); - let _ = NativeBarrier::::initialize_native_barrier(RawOrigin::Root.into(), Some((daily_limit, Default::default())))?; + let _ = NativeBarrier::::initialize_native_barrier( + RawOrigin::Root.into(), + Some((daily_limit, Default::default())), + None + )?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), account("address_1", 0, SEED), diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 678583c6f..03cf6768b 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -192,12 +192,23 @@ pub mod pallet { pub fn initialize_native_barrier( origin: OriginFor, init: Option<(T::Balance, Duration)>, + accounts: Option>, ) -> DispatchResult { ensure_root(origin)?; >::set(init); if >::get().is_none() { >::put(0); } + if let Some(accounts_inner) = accounts { + for account_id in accounts_inner.iter() { + if !RemainingLimit::::contains_key(account_id) { + RemainingLimit::::insert(account_id, T::Balance::zero()); + } + } + Self::deposit_event(Event::AccountsAddedToBarrier { + accounts: accounts_inner, + }); + } Self::deposit_event(Event::NativeBarrierInitialized { init }); Ok(()) } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 83ce7593a..8b7955b1e 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -29,7 +29,8 @@ fn extrinsics_as_normal_user_should_not_work() { assert_noop!( NativeBarrier::initialize_native_barrier( RuntimeOrigin::signed(1), - Some((10u128, Default::default())) + Some((10u128, Default::default())), + None ), sp_runtime::DispatchError::BadOrigin ); @@ -57,7 +58,8 @@ fn extrinsics_as_root_should_work() { ); assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), - Some((10, Duration::default())) + Some((10, Duration::default())), + None )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -104,7 +106,8 @@ fn initialize_native_barrier(daily_limit: u128, start_unix_time: Duration) { assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), - Some((daily_limit, start_unix_time)) + Some((daily_limit, start_unix_time)), + None )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -204,6 +207,7 @@ fn start_in_the_past_should_work() { assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), + None, None )); @@ -301,6 +305,7 @@ fn start_in_the_future_should_work() { assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), + None, None )); From b8e22e15e544d75ccd9f2f573348bf35c9e6d184 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 30 Aug 2023 09:49:15 +0300 Subject: [PATCH 61/69] Revert last commit and addd default daily_limit on initialization again Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/benchmarking.rs | 5 +-- pallets/native-barrier/src/lib.rs | 15 ++------ pallets/native-barrier/src/tests.rs | 40 +++++++++++++--------- 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/pallets/native-barrier/src/benchmarking.rs b/pallets/native-barrier/src/benchmarking.rs index 0e4af1005..cfb66701e 100644 --- a/pallets/native-barrier/src/benchmarking.rs +++ b/pallets/native-barrier/src/benchmarking.rs @@ -40,7 +40,6 @@ benchmarks! { let _ = NativeBarrier::::initialize_native_barrier( RawOrigin::Root.into(), Some((daily_limit, start_unix_time)), - None )?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), @@ -68,7 +67,7 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let daily_limit = T::Balance::zero(); let start_unix_time = Duration::default(); - }: initialize_native_barrier(RawOrigin::Root, Some((daily_limit, start_unix_time)), None) + }: initialize_native_barrier(RawOrigin::Root, Some((daily_limit, start_unix_time))) verify { assert_eq!(NativeBarrier::::get_configurations().unwrap(), (daily_limit, start_unix_time)); } @@ -82,7 +81,6 @@ benchmarks! { let _ = NativeBarrier::::initialize_native_barrier( RawOrigin::Root.into(), Some((daily_limit, start_unix_time)), - None )?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), @@ -106,7 +104,6 @@ benchmarks! { let _ = NativeBarrier::::initialize_native_barrier( RawOrigin::Root.into(), Some((daily_limit, Default::default())), - None )?; let barrier_addresses: Vec = vec![ account("address_0", 0, SEED), diff --git a/pallets/native-barrier/src/lib.rs b/pallets/native-barrier/src/lib.rs index 03cf6768b..f2d918dd8 100644 --- a/pallets/native-barrier/src/lib.rs +++ b/pallets/native-barrier/src/lib.rs @@ -192,23 +192,12 @@ pub mod pallet { pub fn initialize_native_barrier( origin: OriginFor, init: Option<(T::Balance, Duration)>, - accounts: Option>, ) -> DispatchResult { ensure_root(origin)?; >::set(init); if >::get().is_none() { >::put(0); } - if let Some(accounts_inner) = accounts { - for account_id in accounts_inner.iter() { - if !RemainingLimit::::contains_key(account_id) { - RemainingLimit::::insert(account_id, T::Balance::zero()); - } - } - Self::deposit_event(Event::AccountsAddedToBarrier { - accounts: accounts_inner, - }); - } Self::deposit_event(Event::NativeBarrierInitialized { init }); Ok(()) } @@ -224,10 +213,10 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - if Configurations::::get().is_some() { + if let Some((daily_limit, _)) = Configurations::::get() { for account_id in accounts.iter() { if !RemainingLimit::::contains_key(account_id) { - RemainingLimit::::insert(account_id, T::Balance::zero()); + RemainingLimit::::insert(account_id, daily_limit); } } diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 8b7955b1e..0b18d7544 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -30,7 +30,6 @@ fn extrinsics_as_normal_user_should_not_work() { NativeBarrier::initialize_native_barrier( RuntimeOrigin::signed(1), Some((10u128, Default::default())), - None ), sp_runtime::DispatchError::BadOrigin ); @@ -59,7 +58,6 @@ fn extrinsics_as_root_should_work() { assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), Some((10, Duration::default())), - None )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -107,7 +105,6 @@ fn initialize_native_barrier(daily_limit: u128, start_unix_time: Duration) { assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), Some((daily_limit, start_unix_time)), - None )); assert_ok!(NativeBarrier::add_accounts_to_native_barrier( RawOrigin::Root.into(), @@ -126,15 +123,17 @@ fn start_in_the_past_should_work() { initialize_native_barrier(daily_limit, Duration::default()); advance_mock_time(Duration::from_secs(day_in_secs)); - // transfer under limit should not work until next block + // transfer more than 1 limit should not work until next block + assert_eq!(NativeBarrier::get_remaining_limit(1), Some(daily_limit)); assert_err!( - Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2), + Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit + 1), Error::::NativeBarrierLimitExceeded ); NativeBarrier::on_initialize(1); // transfer under limit should now work + assert_eq!(NativeBarrier::get_remaining_limit(1), Some(2 * daily_limit)); assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 2, @@ -142,12 +141,16 @@ fn start_in_the_past_should_work() { )); // transfer more than limit should not work + assert_eq!( + NativeBarrier::get_remaining_limit(1), + Some(daily_limit + daily_limit / 2) + ); assert_err!( - Balances::transfer(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), + Balances::transfer(RuntimeOrigin::signed(1), 2, 2 * daily_limit + 1), Error::::NativeBarrierLimitExceeded ); assert_err!( - Balances::transfer_keep_alive(RuntimeOrigin::signed(1), 2, daily_limit / 2 + 1), + Balances::transfer_keep_alive(RuntimeOrigin::signed(1), 2, 2 * daily_limit + 1), Error::::NativeBarrierLimitExceeded ); assert_err!( @@ -162,11 +165,15 @@ fn start_in_the_past_should_work() { // check that limit has been updated // transfer more than limit should not work + assert_eq!( + NativeBarrier::get_remaining_limit(1), + Some(2 * daily_limit + daily_limit / 2) + ); assert_err!( Balances::transfer( RuntimeOrigin::signed(1), 2, - daily_limit + daily_limit / 2 + 1 + 2 * daily_limit + daily_limit / 2 + 1 ), Error::::NativeBarrierLimitExceeded ); @@ -174,7 +181,7 @@ fn start_in_the_past_should_work() { Balances::transfer_keep_alive( RuntimeOrigin::signed(1), 2, - daily_limit + daily_limit / 2 + 1 + 2 * daily_limit + daily_limit / 2 + 1 ), Error::::NativeBarrierLimitExceeded ); @@ -200,15 +207,15 @@ fn start_in_the_past_should_work() { 3, daily_limit * 5 )); + assert_eq!(NativeBarrier::get_remaining_limit(2), Some(3 * daily_limit)); assert_err!( - Balances::transfer(RuntimeOrigin::signed(2), 2, daily_limit * 2 + 1), + Balances::transfer(RuntimeOrigin::signed(2), 2, 3 * daily_limit + 1), Error::::NativeBarrierLimitExceeded ); assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), None, - None )); // transfer more than limit should work for all @@ -267,7 +274,7 @@ fn start_in_the_future_should_work() { Balances::transfer_keep_alive( RuntimeOrigin::signed(1), 2, - future_days as u128 * daily_limit + 1 + daily_limit + future_days as u128 * daily_limit + 1 ), Error::::NativeBarrierLimitExceeded ); @@ -298,7 +305,7 @@ fn start_in_the_future_should_work() { Balances::transfer( RuntimeOrigin::signed(2), 2, - future_days as u128 * daily_limit + 1 + daily_limit + future_days as u128 * daily_limit + 1 ), Error::::NativeBarrierLimitExceeded ); @@ -306,7 +313,6 @@ fn start_in_the_future_should_work() { assert_ok!(NativeBarrier::initialize_native_barrier( RawOrigin::Root.into(), None, - None )); // transfer more than limit should work for all @@ -351,17 +357,17 @@ fn limits_should_grow_appropriately() { let advance_10 = 10 * 86400; initialize_native_barrier(daily_limit, Duration::from_secs(advance_10)); - loop_on_init_and_assert_accounts(Some(0)); + loop_on_init_and_assert_accounts(Some(daily_limit)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(0)); // roll 20 days (10 days after start) advance_mock_time(Duration::from_secs(advance_10 * 2)); - loop_on_init_and_assert_accounts(Some(daily_limit * 10)); + loop_on_init_and_assert_accounts(Some(daily_limit + daily_limit * 10)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(10)); // roll another 10 days advance_mock_time(Duration::from_secs(advance_10)); - loop_on_init_and_assert_accounts(Some(daily_limit * 20)); + loop_on_init_and_assert_accounts(Some(daily_limit + daily_limit * 20)); assert_eq!(NativeBarrier::get_last_day_processed(), Some(20)); }); } From 290c2af8c9d97e7462c0720a71bad77e64023290 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 30 Aug 2023 09:57:51 +0300 Subject: [PATCH 62/69] Update the in the future tests as well Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/tests.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/pallets/native-barrier/src/tests.rs b/pallets/native-barrier/src/tests.rs index 0b18d7544..08e23e62a 100644 --- a/pallets/native-barrier/src/tests.rs +++ b/pallets/native-barrier/src/tests.rs @@ -247,6 +247,7 @@ fn start_in_the_future_should_work() { let future_days = 10; // transfer more than limit should work + assert_eq!(NativeBarrier::get_remaining_limit(1), None); assert_ok!(Balances::transfer( RuntimeOrigin::signed(1), 2, @@ -255,18 +256,30 @@ fn start_in_the_future_should_work() { initialize_native_barrier(daily_limit, Duration::from_secs(advance_10)); - // limit should be multiple of daily limit (now - epoch_start) - // roll one day + // has 1 daily limit but can over-spend it as the barrier is in the future + assert_eq!(NativeBarrier::get_remaining_limit(1), Some(daily_limit)); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(1), + 2, + daily_limit * 2 + ),); + // The limit should not have been updated + assert_eq!(NativeBarrier::get_remaining_limit(1), Some(daily_limit)); + advance_mock_time(Duration::from_secs(advance_10 * 2)); NativeBarrier::on_initialize(1); // check that limit has been updated // transfer more than limit should not work + assert_eq!( + NativeBarrier::get_remaining_limit(1), + Some(daily_limit + 10 * daily_limit) + ); assert_err!( Balances::transfer( RuntimeOrigin::signed(1), 2, - (future_days as u128 + 1) * daily_limit + 1 + daily_limit + future_days as u128 * daily_limit + 1 ), Error::::NativeBarrierLimitExceeded ); From 74f8f4686e548b52c5e3f25ee4c3fa55f625103c Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 30 Aug 2023 11:07:07 +0300 Subject: [PATCH 63/69] Fix benchmarking compile Signed-off-by: Georgi Zlatarev --- pallets/native-barrier/src/weights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/native-barrier/src/weights.rs b/pallets/native-barrier/src/weights.rs index f79e13b5d..f8af43ca9 100644 --- a/pallets/native-barrier/src/weights.rs +++ b/pallets/native-barrier/src/weights.rs @@ -54,7 +54,7 @@ pub trait WeightInfo { /// Weights for pallet_native_barrier using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl pallet_native_barrier::WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { // Storage: NativeBarrier Configurations (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: NativeBarrier LastDayProcessed (r:1 w:0) From 51f93203b57f0d2dabcc38f8435e0740d5709081 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 30 Aug 2023 13:59:13 +0300 Subject: [PATCH 64/69] Ignore diff_tx-Fees tests temporarily Signed-off-by: Georgi Zlatarev --- runtime/calamari/src/diff_tx_fees.rs | 1 + runtime/manta/src/diff_tx_fees.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/runtime/calamari/src/diff_tx_fees.rs b/runtime/calamari/src/diff_tx_fees.rs index 92fd1f141..0a774d924 100644 --- a/runtime/calamari/src/diff_tx_fees.rs +++ b/runtime/calamari/src/diff_tx_fees.rs @@ -63,6 +63,7 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { (dispatch_info, call_len) } +#[ignore] #[test] fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); diff --git a/runtime/manta/src/diff_tx_fees.rs b/runtime/manta/src/diff_tx_fees.rs index 77e6039f8..d18dff0b2 100644 --- a/runtime/manta/src/diff_tx_fees.rs +++ b/runtime/manta/src/diff_tx_fees.rs @@ -63,6 +63,7 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { (dispatch_info, call_len) } +#[ignore] #[test] fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); From c92c446f006ce59e76d9d1acaf7ab606d772580d Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Wed, 30 Aug 2023 14:16:25 +0300 Subject: [PATCH 65/69] Unignore test and update fees csv Signed-off-by: Georgi Zlatarev --- runtime/calamari/src/diff_tx_fees.rs | 2 -- .../calamari/tx-fees-data/4.4.0-tx-fees.csv | 2 +- runtime/manta/src/diff_tx_fees.rs | 1 - runtime/manta/tx-fees-data/4.4.0-tx-fees.csv | 24 +++++++++---------- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/runtime/calamari/src/diff_tx_fees.rs b/runtime/calamari/src/diff_tx_fees.rs index 0a774d924..4d79e90a9 100644 --- a/runtime/calamari/src/diff_tx_fees.rs +++ b/runtime/calamari/src/diff_tx_fees.rs @@ -63,7 +63,6 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { (dispatch_info, call_len) } -#[ignore] #[test] fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); @@ -141,7 +140,6 @@ fn diff_tx_fees() { } #[test] -#[ignore] fn generate_all_current_extrinsics_tx_fee_to_csv() { const VERSION: &str = env!("CARGO_PKG_VERSION"); const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); diff --git a/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv b/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv index 63fe7e58e..eba00f5d4 100644 --- a/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv +++ b/runtime/calamari/tx-fees-data/4.4.0-tx-fees.csv @@ -241,7 +241,7 @@ zenlink_protocol,bootstrap_update,496532242000,0.496532242,0.0002 zenlink_protocol,bootstrap_refund,495995301000,0.495995301,0.0002 zenlink_protocol,bootstrap_charge_reward,495840000000,0.49584,0.0002 zenlink_protocol,bootstrap_withdraw_reward,495570000000,0.49557,0.0002 -pallet_native_barrier,initialize_native_barrier,495014678000,0.495014678,0.0002 +pallet_native_barrier,initialize_native_barrier,1095014678000,0.495014678,0.0002 pallet_native_barrier,add_accounts_to_native_barrier,495576570000,0.49557657,0.0002 pallet_native_barrier,remove_accounts_from_native_barrier,495419336000,0.495419336,0.0002 frame_system,remark-length=32,511804103000,0.511804103,0.2 diff --git a/runtime/manta/src/diff_tx_fees.rs b/runtime/manta/src/diff_tx_fees.rs index d18dff0b2..77e6039f8 100644 --- a/runtime/manta/src/diff_tx_fees.rs +++ b/runtime/manta/src/diff_tx_fees.rs @@ -63,7 +63,6 @@ fn get_call_details(call: &crate::RuntimeCall) -> (DispatchInfo, u32) { (dispatch_info, call_len) } -#[ignore] #[test] fn diff_tx_fees() { const CURRENT_PATH: &str = env!("CARGO_MANIFEST_DIR"); diff --git a/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv b/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv index d0627cfa3..996866940 100644 --- a/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv +++ b/runtime/manta/tx-fees-data/4.4.0-tx-fees.csv @@ -81,7 +81,7 @@ manta_collator_selection,set_eviction_baseline,4979835900000000,0.0049798359,0.0 manta_collator_selection,set_eviction_tolerance,4979973540000000,0.00497997354,0.0002 pallet_asset_manager,register_asset,5316307190000000,0.00531630719,0.0002 pallet_asset_manager,update_asset_location,5015632340000000,0.00501563234,0.0002 -pallet_asset_manager,update_asset_metadata,5442350760000000,0.00544235076,0.0002 +pallet_asset_manager,update_asset_metadata,5272350760000000,0.00527235076,0.0002 pallet_asset_manager,set_units_per_second,4990541800000000,0.0049905418,0.0002 pallet_asset_manager,mint_asset,5462457200000000,0.0054624572,0.0002 pallet_asset_manager,set_min_xcm_fee,5010191960000000,0.00501019196,0.0002 @@ -240,9 +240,9 @@ zenlink_protocol,bootstrap_update,6232524390000000,0.00623252439,0.0002 zenlink_protocol,bootstrap_refund,5237140050000000,0.00523714005,0.0002 zenlink_protocol,bootstrap_charge_reward,5819700000000000,0.0058197,0.0002 zenlink_protocol,bootstrap_withdraw_reward,5549700000000000,0.0055497,0.0002 -pallet_native_barrier,initialize_native_barrier,4979846780000000,0.00497984678,0.0002 -pallet_native_barrier,add_accounts_to_native_barrier,4985465700000000,0.0049854657,0.0002 -pallet_native_barrier,remove_accounts_from_native_barrier,4983893360000000,0.00498389336,0.0002 +pallet_native_barrier,initialize_native_barrier,4981338030000000,0.00498133803,0.0002 +pallet_native_barrier,add_accounts_to_native_barrier,4985476220000000,0.00498547622,0.0002 +pallet_native_barrier,remove_accounts_from_native_barrier,4983884450000000,0.00498388445,0.0002 frame_system,remark-length=32,5430846460000000,0.00543084646,0.2 frame_system,remark-length=64,5430846460000000,0.00543084646,0.2 frame_system,set_heap_pages,7383150000000000,0.00738315,0.2 @@ -325,7 +325,7 @@ manta_collator_selection,set_eviction_baseline,6114600000000000,0.0061146,0.2 manta_collator_selection,set_eviction_tolerance,6252240000000000,0.00625224,0.2 pallet_asset_manager,register_asset,12915890000000000,0.01291589,0.2 pallet_asset_manager,update_asset_location,11941040000000000,0.01194104,0.2 -pallet_asset_manager,update_asset_metadata,9089460000000000,0.00908946,0.2 +pallet_asset_manager,update_asset_metadata,8919460000000000,0.00891946,0.2 pallet_asset_manager,set_units_per_second,6830500000000000,0.0068305,0.2 pallet_asset_manager,mint_asset,9215900000000000,0.0092159,0.2 pallet_asset_manager,set_min_xcm_fee,6500660000000000,0.00650066,0.2 @@ -484,9 +484,9 @@ zenlink_protocol,bootstrap_update,10053090000000000,0.01005309,0.2 zenlink_protocol,bootstrap_refund,13668750000000000,0.01366875,0.2 zenlink_protocol,bootstrap_charge_reward,6818700000000000,0.0068187,0.2 zenlink_protocol,bootstrap_withdraw_reward,6548700000000000,0.0065487,0.2 -pallet_native_barrier,initialize_native_barrier,6125480000000000,0.00612548,0.2 -pallet_native_barrier,add_accounts_to_native_barrier,11744400000000000,0.0117444,0.2 -pallet_native_barrier,remove_accounts_from_native_barrier,10172060000000000,0.01017206,0.2 +pallet_native_barrier,initialize_native_barrier,7616730000000000,0.00761673,0.2 +pallet_native_barrier,add_accounts_to_native_barrier,11754920000000000,0.01175492,0.2 +pallet_native_barrier,remove_accounts_from_native_barrier,10163150000000000,0.01016315,0.2 frame_system,remark-length=32,5959432300000000,0.0059594323,1 frame_system,remark-length=64,5959432300000000,0.0059594323,1 frame_system,set_heap_pages,16720950000000000,0.01672095,1 @@ -569,7 +569,7 @@ manta_collator_selection,set_eviction_baseline,10658200000000000,0.0106582,1 manta_collator_selection,set_eviction_tolerance,11346400000000000,0.0113464,1 pallet_asset_manager,register_asset,43344650000000000,0.04334465,1 pallet_asset_manager,update_asset_location,39670400000000000,0.0396704,1 -pallet_asset_manager,update_asset_metadata,23692500000000000,0.0236925,1 +pallet_asset_manager,update_asset_metadata,23522500000000000,0.0235225,1 pallet_asset_manager,set_units_per_second,14197700000000000,0.0141977,1 pallet_asset_manager,mint_asset,24244700000000000,0.0242447,1 pallet_asset_manager,set_min_xcm_fee,12468500000000000,0.0124685,1 @@ -728,6 +728,6 @@ zenlink_protocol,bootstrap_update,25350650000000000,0.02535065,1 zenlink_protocol,bootstrap_refund,47428950000000000,0.04742895,1 zenlink_protocol,bootstrap_charge_reward,10818700000000000,0.0108187,1 zenlink_protocol,bootstrap_withdraw_reward,10548700000000000,0.0105487,1 -pallet_native_barrier,initialize_native_barrier,10712600000000000,0.0107126,1 -pallet_native_barrier,add_accounts_to_native_barrier,38807200000000000,0.0388072,1 -pallet_native_barrier,remove_accounts_from_native_barrier,30945500000000000,0.0309455,1 +pallet_native_barrier,initialize_native_barrier,18168850000000000,0.01816885,1 +pallet_native_barrier,add_accounts_to_native_barrier,38859800000000000,0.0388598,1 +pallet_native_barrier,remove_accounts_from_native_barrier,30900950000000000,0.03090095,1 From 9a38533949001b66365fed790bc92c2954603068 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 31 Aug 2023 05:48:15 +0300 Subject: [PATCH 66/69] Bump manta integrations test timeout Signed-off-by: Georgi Zlatarev --- .github/workflows/integration_test_manta.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test_manta.yml b/.github/workflows/integration_test_manta.yml index d03f069b8..1cb44f56d 100644 --- a/.github/workflows/integration_test_manta.yml +++ b/.github/workflows/integration_test_manta.yml @@ -91,7 +91,7 @@ jobs: if: contains(github.event.pull_request.labels.*.name, 'A-manta') needs: [build-node-current] runs-on: runtime-integration-test - timeout-minutes: 240 + timeout-minutes: 420 container: image: ubuntu:20.04 strategy: From a335a241ef92d87830563825d4d9ebb08f0978f5 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 31 Aug 2023 07:29:40 +0300 Subject: [PATCH 67/69] Use orml branch for now Signed-off-by: Georgi Zlatarev --- Cargo.lock | 80 +++++++++++++++++++-------- pallets/asset-manager/Cargo.toml | 2 +- pallets/balances/Cargo.toml | 2 +- pallets/collator-selection/Cargo.toml | 2 +- pallets/farming/Cargo.toml | 2 +- pallets/manta-pay/Cargo.toml | 2 +- pallets/manta-sbt/Cargo.toml | 2 +- pallets/name-service/Cargo.toml | 2 +- pallets/native-barrier/Cargo.toml | 2 +- pallets/pallet-lottery/Cargo.toml | 2 +- pallets/parachain-staking/Cargo.toml | 2 +- pallets/randomness/Cargo.toml | 2 +- pallets/tx-pause/Cargo.toml | 2 +- pallets/vesting/Cargo.toml | 2 +- primitives/manta/Cargo.toml | 2 +- runtime/calamari/Cargo.toml | 4 +- runtime/common/Cargo.toml | 4 +- runtime/integration-tests/Cargo.toml | 4 +- runtime/manta/Cargo.toml | 4 +- 19 files changed, 78 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae929bd78..2ceda29a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1121,7 +1121,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -1205,7 +1205,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "pallet-timestamp", "parity-scale-codec", @@ -4182,7 +4182,7 @@ dependencies = [ "manta-primitives", "manta-runtime", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -5407,7 +5407,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-aura", "pallet-authorship", "pallet-balances 4.4.0", @@ -5493,7 +5493,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "smallvec", @@ -5531,7 +5531,7 @@ dependencies = [ "manta-collator-selection", "manta-primitives", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -6388,6 +6388,24 @@ dependencies = [ "num-traits", ] +[[package]] +name = "orml-traits" +version = "0.4.1-dev" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" +dependencies = [ + "frame-support", + "impl-trait-for-tuples", + "num-traits", + "orml-utilities 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", + "parity-scale-codec", + "scale-info", + "serde", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", +] + [[package]] name = "orml-traits" version = "0.4.1-dev" @@ -6396,7 +6414,7 @@ dependencies = [ "frame-support", "impl-trait-for-tuples", "num-traits", - "orml-utilities", + "orml-utilities 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", "parity-scale-codec", "scale-info", "serde", @@ -6406,6 +6424,20 @@ dependencies = [ "xcm", ] +[[package]] +name = "orml-utilities" +version = "0.4.1-dev" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" +dependencies = [ + "frame-support", + "parity-scale-codec", + "scale-info", + "serde", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "orml-utilities" version = "0.4.1-dev" @@ -6423,10 +6455,10 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#4ff694c4b1e3c4a187410dddf948d86624601a24" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" dependencies = [ "frame-support", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "parity-scale-codec", "sp-runtime", "sp-std", @@ -6437,12 +6469,12 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37#4ff694c4b1e3c4a187410dddf948d86624601a24" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" dependencies = [ "cumulus-primitives-core", "frame-support", "frame-system", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xcm-support", "pallet-xcm", "parity-scale-codec", @@ -6496,7 +6528,7 @@ dependencies = [ "frame-system", "log", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-assets", "pallet-balances 4.4.0", "parity-scale-codec", @@ -6674,7 +6706,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-native-barrier", "pallet-transaction-payment", "parity-scale-codec", @@ -6877,7 +6909,7 @@ dependencies = [ "hex-literal", "log", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.4.0", @@ -7025,7 +7057,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "pallet-parachain-staking", "pallet-preimage", @@ -7065,7 +7097,7 @@ dependencies = [ "manta-pay", "manta-primitives", "manta-util", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.4.0", @@ -7104,7 +7136,7 @@ dependencies = [ "manta-primitives", "manta-util", "num_cpus", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-asset-manager", "pallet-assets", "pallet-balances 4.4.0", @@ -7209,7 +7241,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "pallet-manta-support", "parity-scale-codec", @@ -7229,7 +7261,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", @@ -7352,7 +7384,7 @@ dependencies = [ "log", "manta-collator-selection", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "pallet-session", "parity-scale-codec", @@ -7412,7 +7444,7 @@ dependencies = [ "log", "manta-primitives", "nimbus-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", @@ -7724,7 +7756,7 @@ dependencies = [ "frame-support", "frame-system", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "pallet-balances 4.4.0", "parity-scale-codec", "scale-info", @@ -10103,7 +10135,7 @@ dependencies = [ "frame-system", "lazy_static", "manta-primitives", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", "orml-xtokens", "pallet-asset-manager", "pallet-assets", @@ -15065,7 +15097,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "orml-traits", + "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=polkadot-v0.9.37)", "pallet-balances 4.0.0-dev", "parity-scale-codec", "scale-info", diff --git a/pallets/asset-manager/Cargo.toml b/pallets/asset-manager/Cargo.toml index d4b5a4c4d..d99fd432e 100644 --- a/pallets/asset-manager/Cargo.toml +++ b/pallets/asset-manager/Cargo.toml @@ -21,7 +21,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad xcm = { git = "https://github.com/paritytech/polkadot.git", default-features = false, branch = "release-v0.9.37" } # 3rd party dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml index 411b31cba..bb7d85592 100644 --- a/pallets/balances/Cargo.toml +++ b/pallets/balances/Cargo.toml @@ -21,7 +21,7 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive" sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] diff --git a/pallets/collator-selection/Cargo.toml b/pallets/collator-selection/Cargo.toml index 98193b9a1..b6778057e 100644 --- a/pallets/collator-selection/Cargo.toml +++ b/pallets/collator-selection/Cargo.toml @@ -32,7 +32,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] manta-primitives = { path = "../../primitives/manta" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 5ac208f4c..9c8d19d24 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -24,7 +24,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37", default-features = false } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37", default-features = false } pallet-asset-manager = { path = "../asset-manager", default-features = false, optional = true } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "release-v0.9.37", default-features = false, optional = true } diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index e3ff30315..12198cba2 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -122,7 +122,7 @@ manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5 manta-primitives = { path = "../../primitives/manta", default-features = false } manta-support = { package = "pallet-manta-support", path = "../manta-support", default-features = false } manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", default-features = false } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } pallet-native-barrier = { path = '../native-barrier', default-features = false } [dev-dependencies] diff --git a/pallets/manta-sbt/Cargo.toml b/pallets/manta-sbt/Cargo.toml index ddf7df2cd..05108cc02 100644 --- a/pallets/manta-sbt/Cargo.toml +++ b/pallets/manta-sbt/Cargo.toml @@ -129,7 +129,7 @@ manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0. lazy_static = "1.4.0" manta-crypto = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["getrandom"] } manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.15", features = ["groth16", "parameters", "scale", "download", "test"] } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-asset-manager = { path = "../asset-manager" } pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-balances = { path = "../balances" } diff --git a/pallets/name-service/Cargo.toml b/pallets/name-service/Cargo.toml index fe465f73d..d45eea146 100644 --- a/pallets/name-service/Cargo.toml +++ b/pallets/name-service/Cargo.toml @@ -22,7 +22,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "po sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false } [dev-dependencies] -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/native-barrier/Cargo.toml b/pallets/native-barrier/Cargo.toml index 0a221a688..92341fdfc 100644 --- a/pallets/native-barrier/Cargo.toml +++ b/pallets/native-barrier/Cargo.toml @@ -20,7 +20,7 @@ sp-runtime = { git = 'https://github.com/paritytech/substrate.git', default-feat sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.37" } manta-primitives = { path = '../../primitives/manta', default-features = false } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } [dev-dependencies] pallet-balances = { path = "../balances" } diff --git a/pallets/pallet-lottery/Cargo.toml b/pallets/pallet-lottery/Cargo.toml index f1d506cee..840cf5aa1 100644 --- a/pallets/pallet-lottery/Cargo.toml +++ b/pallets/pallet-lottery/Cargo.toml @@ -40,7 +40,7 @@ rand = { version = "0.8.5", default-features = false, optional = true } calamari-runtime = { path = "../../runtime/calamari", default-features = false } lazy_static = "1.4.0" manta-collator-selection = { path = "../collator-selection", default-features = false } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-preimage = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } pallet-randomness = { path = '../randomness', default-features = false } diff --git a/pallets/parachain-staking/Cargo.toml b/pallets/parachain-staking/Cargo.toml index 7f5577181..db6276094 100644 --- a/pallets/parachain-staking/Cargo.toml +++ b/pallets/parachain-staking/Cargo.toml @@ -37,7 +37,7 @@ pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } [features] default = ["std"] diff --git a/pallets/randomness/Cargo.toml b/pallets/randomness/Cargo.toml index a2a67d92c..5c616a6bb 100644 --- a/pallets/randomness/Cargo.toml +++ b/pallets/randomness/Cargo.toml @@ -27,7 +27,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkad [dev-dependencies] derive_more = "0.99" -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances", features = ["std"] } [features] diff --git a/pallets/tx-pause/Cargo.toml b/pallets/tx-pause/Cargo.toml index ade156998..a1020baa4 100644 --- a/pallets/tx-pause/Cargo.toml +++ b/pallets/tx-pause/Cargo.toml @@ -18,7 +18,7 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkad [dev-dependencies] manta-primitives = { path = '../../primitives/manta' } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } diff --git a/pallets/vesting/Cargo.toml b/pallets/vesting/Cargo.toml index 48eac816b..8aca47098 100644 --- a/pallets/vesting/Cargo.toml +++ b/pallets/vesting/Cargo.toml @@ -22,7 +22,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] chrono = "0.4" manta-primitives = { path = "../../primitives/manta" } -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } pallet-balances = { path = "../balances" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } diff --git a/primitives/manta/Cargo.toml b/primitives/manta/Cargo.toml index 8b5b068ff..e46add363 100644 --- a/primitives/manta/Cargo.toml +++ b/primitives/manta/Cargo.toml @@ -28,7 +28,7 @@ xcm = { git = 'https://github.com/paritytech/polkadot.git', default-features = f xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "polkadot-v0.9.37", default-features = false } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "ghzlatarev/polkadot-v0.9.37", default-features = false } [features] default = ["std"] diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 016257b9c..90cbf6c78 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -108,8 +108,8 @@ runtime-common = { path = '../common', default-features = false } session-key-primitives = { path = '../../primitives/session-keys', default-features = false } # Third party (vendored) dependencies -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 17d74e937..cb3b8343b 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -56,8 +56,8 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.37" } # Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } # Self dependencies pallet-asset-manager = { path = '../../pallets/asset-manager' } diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 4f30200ac..811892523 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -52,8 +52,8 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.37" } # Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37" } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "ghzlatarev/polkadot-v0.9.37" } # Self dependencies calamari-vesting = { path = '../../pallets/vesting' } diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index 9e856cd5a..21b9cdc59 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -85,8 +85,8 @@ xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-feat xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } # Third party (vendored) dependencies -orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } -orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } +orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "ghzlatarev/polkadot-v0.9.37" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } From da094d846f490e16e12cea60f7520bf84d76f042 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 31 Aug 2023 07:33:15 +0300 Subject: [PATCH 68/69] update cargo lock Signed-off-by: Georgi Zlatarev --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ceda29a0..2f5641a0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6391,7 +6391,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -6427,7 +6427,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" dependencies = [ "frame-support", "parity-scale-codec", @@ -6455,7 +6455,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" dependencies = [ "frame-support", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", @@ -6469,7 +6469,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#8806c418b263273637100888b02a01ea595dd838" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" dependencies = [ "cumulus-primitives-core", "frame-support", From d3b705d3b07bb4e83f0e5ade431c172bc1389c64 Mon Sep 17 00:00:00 2001 From: Georgi Zlatarev Date: Thu, 31 Aug 2023 08:59:43 +0300 Subject: [PATCH 69/69] Update orml dep Signed-off-by: Georgi Zlatarev --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f5641a0b..522a3bee3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6391,7 +6391,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#00e9590afdefe603dc2ba2757316759622122096" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -6427,7 +6427,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#00e9590afdefe603dc2ba2757316759622122096" dependencies = [ "frame-support", "parity-scale-codec", @@ -6455,7 +6455,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#00e9590afdefe603dc2ba2757316759622122096" dependencies = [ "frame-support", "orml-traits 0.4.1-dev (git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37)", @@ -6469,7 +6469,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#22a90420f4517a4b9fab81d2ee3937991dc1db54" +source = "git+https://github.com/manta-network/open-runtime-module-library.git?branch=ghzlatarev/polkadot-v0.9.37#00e9590afdefe603dc2ba2757316759622122096" dependencies = [ "cumulus-primitives-core", "frame-support",