diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eb1b02644..27012bd33c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Changelog for the runtimes governed by the Polkadot Fellowship. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## Unreleased + +- Add `pallet-vesting` to Asset Hubs ([polkadot-fellows/runtimes#269](https://github.com/polkadot-fellows/runtimes/pull/269)) + ## [1.2.1] 09.04.2024 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 10aca79f1a..fddf46d540 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,6 +644,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-uniques", "pallet-utility", + "pallet-vesting", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub-router", @@ -771,6 +772,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-uniques", "pallet-utility", + "pallet-vesting", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub-router", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index 748e6d4863..174abb81ed 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -49,6 +49,7 @@ pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-uniques = { workspace = true } pallet-utility = { workspace = true } +pallet-vesting = { workspace = true } sp-api = { workspace = true } sp-block-builder = { workspace = true } sp-consensus-aura = { workspace = true } @@ -138,6 +139,7 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm-bridge-hub-router/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", @@ -178,6 +180,7 @@ try-runtime = [ "pallet-transaction-payment/try-runtime", "pallet-uniques/try-runtime", "pallet-utility/try-runtime", + "pallet-vesting/try-runtime", "pallet-xcm-bridge-hub-router/try-runtime", "pallet-xcm/try-runtime", "parachain-info/try-runtime", @@ -229,6 +232,7 @@ std = [ "pallet-transaction-payment/std", "pallet-uniques/std", "pallet-utility/std", + "pallet-vesting/std", "pallet-xcm-benchmarks?/std", "pallet-xcm-bridge-hub-router/std", "pallet-xcm/std", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 7836f23a21..9579adcdfb 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -39,7 +39,9 @@ use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Verify}, + traits::{ + AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify, + }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, }; @@ -58,7 +60,7 @@ use frame_support::{ traits::{ fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, - TransformOrigin, + TransformOrigin, WithdrawReasons, }, weights::{ConstantMultiplier, Weight}, BoundedVec, PalletId, @@ -229,6 +231,26 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = ConstU32<0>; } +parameter_types! { + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = ExistentialDeposit; + type WeightInfo = weights::pallet_vesting::WeightInfo; + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + /// Note for wallets and implementers: This means that vesting schedules are evaluated with the + /// block number of the Relay Chain, not the parachain. This is because with Coretime and Async + /// Backing, parachain block numbers may not be a good proxy for time. Vesting schedules should + /// be set accordingly. + type BlockNumberProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + parameter_types! { /// Relay Chain `TransactionByteFee` / 10 pub const TransactionByteFee: Balance = system_parachains_constants::kusama::fee::TRANSACTION_BYTE_FEE; @@ -507,7 +529,10 @@ impl InstanceFilter for ProxyType { RuntimeCall::Assets { .. } | RuntimeCall::NftFractionalization { .. } | RuntimeCall::Nfts { .. } | - RuntimeCall::Uniques { .. } + RuntimeCall::Uniques { .. } | + // We allow calling `vest` and merging vesting schedules, but obviously not + // vested transfers. + RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::CancelProxy => matches!( c, @@ -934,6 +959,7 @@ construct_runtime!( Balances: pallet_balances = 10, TransactionPayment: pallet_transaction_payment = 11, AssetTxPayment: pallet_asset_conversion_tx_payment = 13, + Vesting: pallet_vesting = 14, // Collator support. the order of these 5 are important and shall not change. Authorship: pallet_authorship = 20, @@ -1029,6 +1055,7 @@ mod benches { [pallet_session, SessionBench::] [pallet_uniques, Uniques] [pallet_utility, Utility] + [pallet_vesting, Vesting] [pallet_timestamp, Timestamp] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs index de9efc9df7..44039bdf66 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs @@ -35,6 +35,7 @@ pub mod pallet_session; pub mod pallet_timestamp; pub mod pallet_uniques; pub mod pallet_utility; +pub mod pallet_vesting; pub mod pallet_xcm; pub mod pallet_xcm_bridge_hub_router; pub mod paritydb_weights; diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_vesting.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000..236886bb5e --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_vesting.rs @@ -0,0 +1,261 @@ +// Copyright (C) Parity Technologies and the various Polkadot contributors, see Contributions.md +// for a list of specific contributors. +// 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_vesting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ggwpez-ref-hw`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("./kusama-chain-spec.json")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=./kusama-chain-spec.json +// --steps=50 +// --repeat=20 +// --pallet=pallet_vesting +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./kusama-weights/ +// --header=./file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_vesting`. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `348 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 30_917_000 picoseconds. + Weight::from_parts(30_551_282, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_173 + .saturating_add(Weight::from_parts(33_422, 0).saturating_mul(l.into())) + // Standard Error: 2_087 + .saturating_add(Weight::from_parts(71_807, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `348 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 33_025_000 picoseconds. + Weight::from_parts(32_958_120, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_272 + .saturating_add(Weight::from_parts(31_979, 0).saturating_mul(l.into())) + // Standard Error: 2_263 + .saturating_add(Weight::from_parts(63_486, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 32_553_000 picoseconds. + Weight::from_parts(32_149_995, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_260 + .saturating_add(Weight::from_parts(32_155, 0).saturating_mul(l.into())) + // Standard Error: 2_243 + .saturating_add(Weight::from_parts(73_911, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 34_893_000 picoseconds. + Weight::from_parts(34_829_359, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_254 + .saturating_add(Weight::from_parts(28_856, 0).saturating_mul(l.into())) + // Standard Error: 2_231 + .saturating_add(Weight::from_parts(60_032, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `522 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 64_373_000 picoseconds. + Weight::from_parts(65_074_356, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_712 + .saturating_add(Weight::from_parts(44_251, 0).saturating_mul(l.into())) + // Standard Error: 3_046 + .saturating_add(Weight::from_parts(89_076, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn force_vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `625 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `6196` + // Minimum execution time: 65_843_000 picoseconds. + Weight::from_parts(66_423_977, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 1_796 + .saturating_add(Weight::from_parts(47_870, 0).saturating_mul(l.into())) + // Standard Error: 3_196 + .saturating_add(Weight::from_parts(108_650, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `449 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 33_450_000 picoseconds. + Weight::from_parts(32_808_904, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_191 + .saturating_add(Weight::from_parts(35_436, 0).saturating_mul(l.into())) + // Standard Error: 2_201 + .saturating_add(Weight::from_parts(76_265, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `449 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 35_949_000 picoseconds. + Weight::from_parts(35_614_525, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_234 + .saturating_add(Weight::from_parts(34_681, 0).saturating_mul(l.into())) + // Standard Error: 2_280 + .saturating_add(Weight::from_parts(64_081, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `522 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 37_194_000 picoseconds. + Weight::from_parts(37_018_633, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_538 + .saturating_add(Weight::from_parts(31_949, 0).saturating_mul(l.into())) + // Standard Error: 2_841 + .saturating_add(Weight::from_parts(75_135, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 6558b3d7b5..157e013260 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -48,6 +48,7 @@ pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-uniques = { workspace = true } pallet-utility = { workspace = true } +pallet-vesting = { workspace = true } sp-api = { workspace = true } sp-block-builder = { workspace = true } sp-consensus-aura = { workspace = true } @@ -129,6 +130,7 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm-bridge-hub-router/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", @@ -167,6 +169,7 @@ try-runtime = [ "pallet-transaction-payment/try-runtime", "pallet-uniques/try-runtime", "pallet-utility/try-runtime", + "pallet-vesting/try-runtime", "pallet-xcm-bridge-hub-router/try-runtime", "pallet-xcm/try-runtime", "parachain-info/try-runtime", @@ -216,6 +219,7 @@ std = [ "pallet-transaction-payment/std", "pallet-uniques/std", "pallet-utility/std", + "pallet-vesting/std", "pallet-xcm-benchmarks?/std", "pallet-xcm-bridge-hub-router/std", "pallet-xcm/std", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 3f95d576bb..38115d330f 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -75,7 +75,7 @@ use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, ConstU128, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, Verify}, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, }; @@ -95,7 +95,7 @@ use frame_support::{ traits::{ fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, NeverEnsureOrigin, - TransformOrigin, + TransformOrigin, WithdrawReasons, }, weights::{ConstantMultiplier, Weight}, PalletId, @@ -249,6 +249,26 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = ConstU32<0>; } +parameter_types! { + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = ExistentialDeposit; + type WeightInfo = weights::pallet_vesting::WeightInfo; + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + /// Note for wallets and implementers: This means that vesting schedules are evaluated with the + /// block number of the Relay Chain, not the parachain. This is because with Coretime and Async + /// Backing, parachain block numbers may not be a good proxy for time. Vesting schedules should + /// be set accordingly. + type BlockNumberProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + parameter_types! { /// Relay Chain `TransactionByteFee` / 10 pub const TransactionByteFee: Balance = system_parachains_constants::polkadot::fee::TRANSACTION_BYTE_FEE; @@ -436,7 +456,10 @@ impl InstanceFilter for ProxyType { RuntimeCall::Balances { .. } | RuntimeCall::Assets { .. } | RuntimeCall::Nfts { .. } | - RuntimeCall::Uniques { .. } + RuntimeCall::Uniques { .. } | + // We allow calling `vest` and merging vesting schedules, but obviously not + // vested transfers. + RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::CancelProxy => matches!( c, @@ -926,6 +949,7 @@ construct_runtime!( Balances: pallet_balances = 10, TransactionPayment: pallet_transaction_payment = 11, AssetTxPayment: pallet_asset_conversion_tx_payment = 13, + Vesting: pallet_vesting = 14, // Collator support. the order of these 5 are important and shall not change. Authorship: pallet_authorship = 20, @@ -1015,6 +1039,7 @@ mod benches { [pallet_session, SessionBench::] [pallet_uniques, Uniques] [pallet_utility, Utility] + [pallet_vesting, Vesting] [pallet_timestamp, Timestamp] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs index e64eef645d..5f9dd30b25 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs @@ -34,6 +34,7 @@ pub mod pallet_session; pub mod pallet_timestamp; pub mod pallet_uniques; pub mod pallet_utility; +pub mod pallet_vesting; pub mod pallet_xcm; pub mod pallet_xcm_bridge_hub_router; pub mod paritydb_weights; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_vesting.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000..b64738799b --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_vesting.rs @@ -0,0 +1,261 @@ +// Copyright (C) Parity Technologies and the various Polkadot contributors, see Contributions.md +// for a list of specific contributors. +// 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_vesting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ggwpez-ref-hw`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("./polkadot-chain-spec.json")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=./polkadot-chain-spec.json +// --steps=50 +// --repeat=20 +// --pallet=pallet_vesting +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./polkadot-weights/ +// --header=./file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_vesting`. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `348 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 30_457_000 picoseconds. + Weight::from_parts(30_003_923, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_019 + .saturating_add(Weight::from_parts(35_627, 0).saturating_mul(l.into())) + // Standard Error: 1_814 + .saturating_add(Weight::from_parts(59_288, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `348 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 32_180_000 picoseconds. + Weight::from_parts(32_379_213, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_306 + .saturating_add(Weight::from_parts(32_647, 0).saturating_mul(l.into())) + // Standard Error: 2_324 + .saturating_add(Weight::from_parts(57_435, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 32_045_000 picoseconds. + Weight::from_parts(30_913_615, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_193 + .saturating_add(Weight::from_parts(46_337, 0).saturating_mul(l.into())) + // Standard Error: 2_123 + .saturating_add(Weight::from_parts(74_354, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 33_984_000 picoseconds. + Weight::from_parts(33_400_020, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_140 + .saturating_add(Weight::from_parts(38_571, 0).saturating_mul(l.into())) + // Standard Error: 2_029 + .saturating_add(Weight::from_parts(72_151, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `522 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 63_632_000 picoseconds. + Weight::from_parts(64_542_490, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_960 + .saturating_add(Weight::from_parts(40_280, 0).saturating_mul(l.into())) + // Standard Error: 3_488 + .saturating_add(Weight::from_parts(86_697, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn force_vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `625 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `6196` + // Minimum execution time: 65_338_000 picoseconds. + Weight::from_parts(66_120_449, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 2_003 + .saturating_add(Weight::from_parts(45_256, 0).saturating_mul(l.into())) + // Standard Error: 3_565 + .saturating_add(Weight::from_parts(88_738, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `449 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 32_789_000 picoseconds. + Weight::from_parts(32_683_094, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_395 + .saturating_add(Weight::from_parts(28_000, 0).saturating_mul(l.into())) + // Standard Error: 2_577 + .saturating_add(Weight::from_parts(69_301, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `449 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 35_364_000 picoseconds. + Weight::from_parts(34_412_189, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 983 + .saturating_add(Weight::from_parts(41_189, 0).saturating_mul(l.into())) + // Standard Error: 1_815 + .saturating_add(Weight::from_parts(75_023, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `522 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 36_296_000 picoseconds. + Weight::from_parts(35_378_690, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_381 + .saturating_add(Weight::from_parts(43_058, 0).saturating_mul(l.into())) + // Standard Error: 2_551 + .saturating_add(Weight::from_parts(92_179, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +}