From 1555f1a4596628bd98610d92ec2d028db6907ff2 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Wed, 28 Aug 2024 21:49:13 +0200 Subject: [PATCH 01/17] vesting mbm --- Cargo.lock | 22 ++++ Cargo.toml | 1 + pallets/vesting-mbm/Cargo.toml | 53 ++++++++++ pallets/vesting-mbm/src/benchmarks.rs | 73 +++++++++++++ pallets/vesting-mbm/src/lib.rs | 146 ++++++++++++++++++++++++++ pallets/vesting-mbm/src/mock.rs | 140 ++++++++++++++++++++++++ pallets/vesting-mbm/src/tests.rs | 125 ++++++++++++++++++++++ pallets/vesting-mbm/src/weights.rs | 89 ++++++++++++++++ runtime/shibuya/Cargo.toml | 3 + runtime/shibuya/src/lib.rs | 13 ++- 10 files changed, 664 insertions(+), 1 deletion(-) create mode 100644 pallets/vesting-mbm/Cargo.toml create mode 100644 pallets/vesting-mbm/src/benchmarks.rs create mode 100644 pallets/vesting-mbm/src/lib.rs create mode 100644 pallets/vesting-mbm/src/mock.rs create mode 100644 pallets/vesting-mbm/src/tests.rs create mode 100644 pallets/vesting-mbm/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 3da296baa..2a774b07b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14469,6 +14469,7 @@ dependencies = [ "staging-xcm-builder", "staging-xcm-executor", "substrate-wasm-builder", + "vesting-mbm", "xcm-fee-payment-runtime-api", ] @@ -17016,6 +17017,27 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vesting-mbm" +version = "1.0.0" +dependencies = [ + "astar-primitives", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-balances", + "pallet-migrations", + "pallet-vesting", + "parity-scale-codec", + "scale-info", + "serde_json", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.11.0)", +] + [[package]] name = "void" version = "1.0.2" diff --git a/Cargo.toml b/Cargo.toml index 159349e33..bbf3a5a70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -292,6 +292,7 @@ astar-xcm-benchmarks = { path = "./pallets/astar-xcm-benchmarks", default-featur pallet-static-price-provider = { path = "./pallets/static-price-provider", default-features = false } pallet-price-aggregator = { path = "./pallets/price-aggregator", default-features = false } pallet-collective-proxy = { path = "./pallets/collective-proxy", default-features = false } +vesting-mbm = { path = "./pallets/vesting-mbm", default-features = false } dapp-staking-v3-runtime-api = { path = "./pallets/dapp-staking-v3/rpc/runtime-api", default-features = false } diff --git a/pallets/vesting-mbm/Cargo.toml b/pallets/vesting-mbm/Cargo.toml new file mode 100644 index 000000000..d630cbb1b --- /dev/null +++ b/pallets/vesting-mbm/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "vesting-mbm" +version = "1.0.0" +license = "GPL-3.0-or-later" +description = "Vesting multi block migration to support async backing" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +astar-primitives = { workspace = true } +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +log = { workspace = true } +pallet-vesting = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +sp-arithmetic = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +[dev-dependencies] +pallet-balances = { workspace = true } +pallet-migrations = { workspace = true } +serde_json = { workspace = true } + +[features] +default = ["std"] +std = [ + "sp-std/std", + "sp-io/std", + "log/std", + "scale-info/std", + "parity-scale-codec/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking?/std", + "sp-arithmetic/std", + "sp-runtime/std", + "astar-primitives/std", + "pallet-vesting/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "astar-primitives/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/pallets/vesting-mbm/src/benchmarks.rs b/pallets/vesting-mbm/src/benchmarks.rs new file mode 100644 index 000000000..0a773207e --- /dev/null +++ b/pallets/vesting-mbm/src/benchmarks.rs @@ -0,0 +1,73 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +#![cfg(feature = "runtime-benchmarks")] + +use crate::{Config, Pallet}; +use frame_benchmarking::v2::*; +use frame_support::traits::Currency; +use frame_support::{assert_ok, migrations::SteppedMigration, weights::WeightMeter}; +use pallet_vesting::VestingInfo; +use sp_runtime::traits::StaticLookup; +use sp_std::vec; + +#[benchmarks] +mod benches { + use super::*; + + /// Benchmark a single step of vesting migration. + #[benchmark] + fn step(x: Linear<1u32, { ::MAX_VESTING_SCHEDULES }>) { + let alice: T::AccountId = account("alice", 0, 1); + let bob: T::AccountId = account("bob", 0, 2); + + for _ in 0..x { + let _ = T::Currency::make_free_balance_be(&alice, 1_000_000u32.into()); + assert_ok!(pallet_vesting::Pallet::::vested_transfer( + frame_system::RawOrigin::Signed(alice.clone()).into(), + T::Lookup::unlookup(bob.clone()), + VestingInfo::new(1_000_000u32.into(), 10u32.into(), 0u32.into()), + )); + } + + let mut meter = WeightMeter::new(); + + #[block] + { + // start from some cursor to avoid counting prefix read + crate::LazyMigration::>::step(None, &mut meter) + .unwrap(); + } + + let mut expected = vec![]; + for _ in 0..x { + expected.push(VestingInfo::new( + 999_990u32.into(), + 5u32.into(), + 1u32.into(), + )); + } + + assert_eq!( + pallet_vesting::Vesting::::get(&bob).unwrap().to_vec(), + expected + ); + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); +} diff --git a/pallets/vesting-mbm/src/lib.rs b/pallets/vesting-mbm/src/lib.rs new file mode 100644 index 000000000..41b926d34 --- /dev/null +++ b/pallets/vesting-mbm/src/lib.rs @@ -0,0 +1,146 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::{ + migrations::{MigrationId, SteppedMigration, SteppedMigrationError}, + weights::WeightMeter, +}; +use pallet_vesting::{Vesting, VestingInfo}; +use sp_arithmetic::traits::{SaturatedConversion, Saturating}; +use sp_runtime::{traits::BlockNumberProvider, Percent}; + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarks; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + +pub mod weights; + +const LOG_TARGET: &str = "mbm::vesting"; +const PALLET_MIGRATIONS_ID: &[u8; 18] = b"pallet-vesting-mbm"; + +pub struct LazyMigration(core::marker::PhantomData<(T, W)>); + +impl SteppedMigration for LazyMigration +where + T: frame_system::Config + pallet_vesting::Config, +{ + type Cursor = ::AccountId; + // Without the explicit length here the construction of the ID would not be infallible. + type Identifier = MigrationId<18>; + + /// The identifier of this migration. Which should be globally unique. + fn id() -> Self::Identifier { + MigrationId { + pallet_id: *PALLET_MIGRATIONS_ID, + version_from: 0, + version_to: 1, + } + } + + fn step( + mut cursor: Option, + meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + let required = W::step(T::MAX_VESTING_SCHEDULES); + // If there is not enough weight for a single step, return an error. This case can be + // problematic if it is the first migration that ran in this block. But there is nothing + // that we can do about it here. + if meter.remaining().any_lt(required) { + return Err(SteppedMigrationError::InsufficientWeight { required }); + } + + let mut count = 0u32; + let para_block_number = frame_system::Pallet::::block_number(); + let current_block_number = T::BlockNumberProvider::current_block_number(); + + // We loop here to do as much progress as possible per step. + loop { + // stop when remaining weight is lower than step max weight + if meter.remaining().any_lt(required) { + break; + } + + let mut iter = if let Some(last_key) = cursor { + // If a cursor is provided, start iterating from the stored value + // corresponding to the last key processed in the previous step. + // Note that this only works if the old and the new map use the same way to hash + // storage keys. + Vesting::::iter_from(Vesting::::hashed_key_for(last_key)) + } else { + // If no cursor is provided, start iterating from the beginning. + Vesting::::iter() + }; + + // If there's a next item in the iterator, perform the migration. + if let Some((ref last_key, mut schedules)) = iter.next() { + for schedule in schedules.iter_mut() { + // remaining locked balance + let locked = schedule.locked_at::(para_block_number); + // reduce unlock `per_block` into half + let per_block = Percent::from_percent(50) * schedule.per_block(); + // remaining blocks to start vesting if vesting hasn't started yet + // remaining blocks will be doubled + let remaining_blocks = schedule + .starting_block() + .saturating_sub(para_block_number) + .saturating_mul(2u32.into()); + let start_block = current_block_number.saturating_add(remaining_blocks); + + *schedule = VestingInfo::new(locked, per_block, start_block); + } + + // consume the exact weight + meter.consume(W::step(schedules.len().saturated_into())); + + // Override vesting schedules + Vesting::::insert(last_key, schedules); + + // inc counter + count.saturating_inc(); + + // Return the processed key as the new cursor. + cursor = Some(last_key.clone()) + } else { + // Signal that the migration is complete (no more items to process). + cursor = None; + break; + } + } + log::debug!(target: LOG_TARGET, "migrated {count:?} entries"); + Ok(cursor) + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_vesting::Config {} +} diff --git a/pallets/vesting-mbm/src/mock.rs b/pallets/vesting-mbm/src/mock.rs new file mode 100644 index 000000000..dc4896a98 --- /dev/null +++ b/pallets/vesting-mbm/src/mock.rs @@ -0,0 +1,140 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +#![cfg(test)] + +use frame_support::{ + construct_runtime, derive_impl, + migrations::MultiStepMigrator, + pallet_prelude::*, + parameter_types, + traits::{OnFinalize, OnInitialize, WithdrawReasons}, +}; +use sp_runtime::{traits::ConvertInto, BuildStorage}; + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub struct Runtime { + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, + MultiBlockMigrations: pallet_migrations, + Pallet: crate, + } +); + +impl crate::Config for Runtime {} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + type Block = Block; + type MultiBlockMigrator = MultiBlockMigrations; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Runtime { + type AccountStore = System; + type ExistentialDeposit = ExistentialDeposit; +} + +parameter_types! { + pub const MaxServiceWeight: Weight = Weight::MAX.div(10); +} + +#[derive_impl(pallet_migrations::config_preludes::TestDefaultConfig)] +impl pallet_migrations::Config for Runtime { + // #[cfg(feature = "runtime-benchmarks")] + // type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + // #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = (crate::LazyMigration>,); + type MigrationStatusHandler = (); + type MaxServiceWeight = MaxServiceWeight; +} + +parameter_types! { + pub const MinVestedTransfer: u64 = 256 * 2; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); + pub static ExistentialDeposit: u64 = 1; +} + +impl pallet_vesting::Config for Runtime { + type BlockNumberToBalance = ConvertInto; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + const MAX_VESTING_SCHEDULES: u32 = 3; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + type BlockNumberProvider = System; +} + +#[derive(Default)] +pub struct ExtBuilder; + +pub(crate) const ALICE: u64 = 1; +pub(crate) const BOB: u64 = 2; +pub(crate) const CHARLIE: u64 = 3; +pub(crate) const DAVE: u64 = 4; + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, 100), (BOB, 100), (CHARLIE, 1000), (DAVE, 800)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let vesting = vec![ + // who, start_at, length, liquid + (ALICE, 0, 10, 0), + (BOB, 10, 10, 0), + (CHARLIE, 20, 10, 0), + (DAVE, 5, 20, 400), + ]; + + pallet_vesting::GenesisConfig:: { vesting } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + ExtBuilder::default().build() +} + +#[allow(dead_code)] +pub fn run_to_block(n: u64) { + assert!(System::block_number() < n); + while System::block_number() < n { + let b = System::block_number(); + AllPalletsWithSystem::on_finalize(b); + // Done by Executive: + ::MultiBlockMigrator::step(); + System::set_block_number(b + 1); + AllPalletsWithSystem::on_initialize(b + 1); + } +} diff --git a/pallets/vesting-mbm/src/tests.rs b/pallets/vesting-mbm/src/tests.rs new file mode 100644 index 000000000..008daf3cd --- /dev/null +++ b/pallets/vesting-mbm/src/tests.rs @@ -0,0 +1,125 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +#![cfg(test)] + +use crate::mock::{ + new_test_ext, run_to_block, AllPalletsWithSystem, Balances, RuntimeOrigin, Vesting, ALICE, BOB, + CHARLIE, DAVE, +}; +use frame_support::{ + assert_ok, + traits::{OnRuntimeUpgrade, VestingSchedule}, +}; +use pallet_balances::{BalanceLock, Reasons}; +use pallet_vesting::VestingInfo; + +#[test] +fn migrate_to_new_block_time() { + new_test_ext().execute_with(|| { + assert_eq!(Vesting::vesting_balance(&ALICE), Some(90)); // 10 vested at block 1, 10 per block + assert_eq!(Vesting::vesting_balance(&BOB), Some(100)); + assert_eq!(Vesting::vesting_balance(&CHARLIE), Some(1000)); + assert_eq!(Vesting::vesting_balance(&DAVE), Some(400)); + + run_to_block(10); + + assert_eq!(Vesting::vesting_balance(&ALICE), Some(0)); // Alice fully vested at block 10 + assert_eq!(Vesting::vesting_balance(&BOB), Some(100)); // starts now, 10 per block + assert_eq!(Vesting::vesting_balance(&CHARLIE), Some(1000)); // starts at 20 + assert_eq!(Vesting::vesting_balance(&DAVE), Some(300)); // starts vesting at block 5, 20 per block + + assert_eq!( + Vesting::vesting(&BOB).unwrap().to_vec(), + vec![VestingInfo::new(100, 10, 10)] + ); + assert_eq!( + Vesting::vesting(&CHARLIE).unwrap().to_vec(), + vec![VestingInfo::new(1000, 100, 20)] + ); + assert_eq!( + Vesting::vesting(&DAVE).unwrap().to_vec(), + vec![VestingInfo::new(400, 20, 5)] + ); + + // onboard MBMs + AllPalletsWithSystem::on_runtime_upgrade(); + run_to_block(11); + + assert_eq!(Vesting::vesting_balance(&ALICE), Some(0)); // Alice remains the same + assert_eq!(Vesting::vesting_balance(&BOB), Some(95)); // 5 unlocked + assert_eq!(Vesting::vesting_balance(&CHARLIE), Some(1000)); // starts at 30 now, doubled remaining blocks + assert_eq!(Vesting::vesting_balance(&DAVE), Some(290)); // 10 unlocked + + assert_eq!( + Vesting::vesting(&BOB).unwrap().to_vec(), + vec![VestingInfo::new(100, 5, 10)] + ); + assert_eq!( + Vesting::vesting(&CHARLIE).unwrap().to_vec(), + vec![VestingInfo::new(1000, 50, 30)] + ); + assert_eq!( + Vesting::vesting(&DAVE).unwrap().to_vec(), + vec![VestingInfo::new(300, 10, 10)] + ); + + // lock is updated when `PalletVesting::vest` is called + assert_eq!( + Balances::locks(&BOB).to_vec(), + vec![BalanceLock { + id: *b"vesting ", + amount: 100, + reasons: Reasons::Misc, + }] + ); + // call vest to unlock vested funds + assert_ok!(Vesting::vest(RuntimeOrigin::signed(BOB))); + assert_eq!( + Balances::locks(&BOB).to_vec(), + vec![BalanceLock { + id: *b"vesting ", + amount: 95, + reasons: Reasons::Misc, + }] + ); + + run_to_block(29); + assert_eq!(Vesting::vesting_balance(&BOB), Some(5)); + // Bob will fully vest at 30 + run_to_block(30); + assert_eq!(Vesting::vesting_balance(&BOB), Some(0)); + // call vest to unlock vested funds + assert_ok!(Vesting::vest(RuntimeOrigin::signed(BOB))); + assert_eq!(Balances::locks(&BOB).to_vec(), vec![]); + + run_to_block(39); + assert_eq!(Vesting::vesting_balance(&CHARLIE), Some(550)); // started vesting at 30 + assert_eq!(Vesting::vesting_balance(&DAVE), Some(10)); + + // Dave will fully vest at 40 + run_to_block(40); + assert_eq!(Vesting::vesting_balance(&DAVE), Some(0)); + + run_to_block(49); + assert_eq!(Vesting::vesting_balance(&CHARLIE), Some(50)); + // Charlie will fully vest at 50, (50 per block starting at block 30) + run_to_block(50); + assert_eq!(Vesting::vesting_balance(&CHARLIE), Some(0)); + }); +} diff --git a/pallets/vesting-mbm/src/weights.rs b/pallets/vesting-mbm/src/weights.rs new file mode 100644 index 000000000..156902a08 --- /dev/null +++ b/pallets/vesting-mbm/src/weights.rs @@ -0,0 +1,89 @@ + +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +//! Autogenerated weights for vesting_mbm +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-08-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Ermals-MacBook-Pro-M1.local`, CPU: `` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("shibuya-dev"), DB CACHE: 1024 + +// Executed Command: +// target/release/astar-collator +// benchmark +// pallet +// --chain=shibuya-dev +// --steps=50 +// --repeat=20 +// --pallet=vesting_mbm +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./pallets/vesting-mbm/src/weights.rs +// --template=./scripts/templates/weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for vesting_mbm. +pub trait WeightInfo { + fn step(x: u32, ) -> Weight; +} + +/// Weights for vesting_mbm using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `Vesting::Vesting` (r:2 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 28]`. + fn step(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `316 + x * (36 ±0)` + // Estimated: `8054` + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(12_088_198, 8054) + // Standard Error: 2_315 + .saturating_add(Weight::from_parts(75_271, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: `Vesting::Vesting` (r:2 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 28]`. + fn step(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `316 + x * (36 ±0)` + // Estimated: `8054` + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(12_088_198, 8054) + // Standard Error: 2_315 + .saturating_add(Weight::from_parts(75_271, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index 1890be8eb..f076e4e5d 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -76,6 +76,7 @@ pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-treasury = { workspace = true } pallet-utility = { workspace = true } pallet-vesting = { workspace = true } +vesting-mbm = { workspace = true } # cumulus dependencies cumulus-pallet-aura-ext = { workspace = true } @@ -260,6 +261,7 @@ std = [ "pallet-xcm-benchmarks?/std", "precompile-utils/std", "scale-info/std", + "vesting-mbm/std" ] runtime-benchmarks = [ "astar-xcm-benchmarks/runtime-benchmarks", @@ -317,6 +319,7 @@ runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "parachains-common/runtime-benchmarks", "orml-oracle/runtime-benchmarks", + "vesting-mbm/runtime-benchmarks" ] try-runtime = [ "fp-self-contained/try-runtime", diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index f875902e9..a8450369b 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -714,6 +714,9 @@ impl pallet_vesting::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type BlockNumberToBalance = ConvertInto; + #[cfg(feature = "runtime-benchmarks")] + type MinVestedTransfer = ConstU128<1>; + #[cfg(not(feature = "runtime-benchmarks"))] type MinVestedTransfer = MinVestedTransfer; type WeightInfo = pallet_vesting::weights::SubstrateWeight; type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; @@ -1521,7 +1524,8 @@ parameter_types! { impl pallet_migrations::Config for Runtime { type RuntimeEvent = RuntimeEvent; #[cfg(not(feature = "runtime-benchmarks"))] - type Migrations = (); + type Migrations = + (vesting_mbm::LazyMigration>,); // Benchmarks need mocked migrations to guarantee that they succeed. #[cfg(feature = "runtime-benchmarks")] type Migrations = pallet_migrations::mock_helpers::MockedMigrations; @@ -1533,6 +1537,9 @@ impl pallet_migrations::Config for Runtime { type WeightInfo = pallet_migrations::weights::SubstrateWeight; } +#[cfg(feature = "runtime-benchmarks")] +impl vesting_mbm::Config for Runtime {} + construct_runtime!( pub struct Runtime { @@ -1599,6 +1606,9 @@ construct_runtime!( CollectiveProxy: pallet_collective_proxy = 109, MultiBlockMigrations: pallet_migrations = 120, + + #[cfg(feature = "runtime-benchmarks")] + VestingMBM: vesting_mbm = 250, } ); @@ -1776,6 +1786,7 @@ mod benches { [pallet_price_aggregator, PriceAggregator] [pallet_collective_proxy, CollectiveProxy] [orml_oracle, Oracle] + [vesting_mbm, VestingMBM] ); } From 12e337ae0f62f8c3487282c4b66f114cbdd0cb77 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Wed, 28 Aug 2024 21:57:59 +0200 Subject: [PATCH 02/17] cleanup --- pallets/vesting-mbm/src/benchmarks.rs | 6 +++--- pallets/vesting-mbm/src/mock.rs | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pallets/vesting-mbm/src/benchmarks.rs b/pallets/vesting-mbm/src/benchmarks.rs index 0a773207e..c0d401bcb 100644 --- a/pallets/vesting-mbm/src/benchmarks.rs +++ b/pallets/vesting-mbm/src/benchmarks.rs @@ -20,8 +20,9 @@ use crate::{Config, Pallet}; use frame_benchmarking::v2::*; -use frame_support::traits::Currency; -use frame_support::{assert_ok, migrations::SteppedMigration, weights::WeightMeter}; +use frame_support::{ + assert_ok, migrations::SteppedMigration, traits::Currency, weights::WeightMeter, +}; use pallet_vesting::VestingInfo; use sp_runtime::traits::StaticLookup; use sp_std::vec; @@ -49,7 +50,6 @@ mod benches { #[block] { - // start from some cursor to avoid counting prefix read crate::LazyMigration::>::step(None, &mut meter) .unwrap(); } diff --git a/pallets/vesting-mbm/src/mock.rs b/pallets/vesting-mbm/src/mock.rs index dc4896a98..61f83c08a 100644 --- a/pallets/vesting-mbm/src/mock.rs +++ b/pallets/vesting-mbm/src/mock.rs @@ -60,9 +60,6 @@ parameter_types! { #[derive_impl(pallet_migrations::config_preludes::TestDefaultConfig)] impl pallet_migrations::Config for Runtime { - // #[cfg(feature = "runtime-benchmarks")] - // type Migrations = pallet_migrations::mock_helpers::MockedMigrations; - // #[cfg(not(feature = "runtime-benchmarks"))] type Migrations = (crate::LazyMigration>,); type MigrationStatusHandler = (); type MaxServiceWeight = MaxServiceWeight; From 48ec7781a3569c3cb6f13f5b3a9f3ee5fdee2a6e Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Thu, 29 Aug 2024 09:38:22 +0200 Subject: [PATCH 03/17] update weights --- pallets/vesting-mbm/src/weights.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pallets/vesting-mbm/src/weights.rs b/pallets/vesting-mbm/src/weights.rs index 156902a08..52940c768 100644 --- a/pallets/vesting-mbm/src/weights.rs +++ b/pallets/vesting-mbm/src/weights.rs @@ -22,11 +22,11 @@ //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 //! DATE: 2024-08-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Ermals-MacBook-Pro-M1.local`, CPU: `` +//! HOSTNAME: `gh-runner-01-ovh`, CPU: `Intel(R) Xeon(R) E-2236 CPU @ 3.40GHz` //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("shibuya-dev"), DB CACHE: 1024 // Executed Command: -// target/release/astar-collator +// ./target/release/astar-collator // benchmark // pallet // --chain=shibuya-dev @@ -36,7 +36,7 @@ // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./pallets/vesting-mbm/src/weights.rs +// --output=./benchmark-results/shibuya-dev/mbm_weights.rs // --template=./scripts/templates/weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -61,10 +61,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `316 + x * (36 ±0)` // Estimated: `8054` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(12_088_198, 8054) - // Standard Error: 2_315 - .saturating_add(Weight::from_parts(75_271, 0).saturating_mul(x.into())) + // Minimum execution time: 13_079_000 picoseconds. + Weight::from_parts(13_513_131, 8054) + // Standard Error: 723 + .saturating_add(Weight::from_parts(102_389, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -79,10 +79,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `316 + x * (36 ±0)` // Estimated: `8054` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(12_088_198, 8054) - // Standard Error: 2_315 - .saturating_add(Weight::from_parts(75_271, 0).saturating_mul(x.into())) + // Minimum execution time: 13_079_000 picoseconds. + Weight::from_parts(13_513_131, 8054) + // Standard Error: 723 + .saturating_add(Weight::from_parts(102_389, 0).saturating_mul(x.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } From fecbfc091410bf64a2293f462b0e81e498ea14b0 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Thu, 29 Aug 2024 10:46:46 +0200 Subject: [PATCH 04/17] fix feature --- pallets/vesting-mbm/Cargo.toml | 8 ++++++++ runtime/shibuya/Cargo.toml | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pallets/vesting-mbm/Cargo.toml b/pallets/vesting-mbm/Cargo.toml index d630cbb1b..a990fa01d 100644 --- a/pallets/vesting-mbm/Cargo.toml +++ b/pallets/vesting-mbm/Cargo.toml @@ -51,3 +51,11 @@ runtime-benchmarks = [ "pallet-vesting/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] + +try-runtime = [ + "frame-support/try-runtime", + "astar-primitives/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", + "pallet-vesting/try-runtime", +] diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index f076e4e5d..3dbd0cbe6 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -261,7 +261,7 @@ std = [ "pallet-xcm-benchmarks?/std", "precompile-utils/std", "scale-info/std", - "vesting-mbm/std" + "vesting-mbm/std", ] runtime-benchmarks = [ "astar-xcm-benchmarks/runtime-benchmarks", @@ -319,7 +319,7 @@ runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "parachains-common/runtime-benchmarks", "orml-oracle/runtime-benchmarks", - "vesting-mbm/runtime-benchmarks" + "vesting-mbm/runtime-benchmarks", ] try-runtime = [ "fp-self-contained/try-runtime", @@ -376,6 +376,7 @@ try-runtime = [ "pallet-chain-extension-assets/try-runtime", "polkadot-runtime-common/try-runtime", "sp-runtime/try-runtime", + "vesting-mbm/try-runtime", ] evm-tracing = [ "moonbeam-evm-tracer", From a6ee8e6351ae8e3473a14d5dfc852efb8f8a3373 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Thu, 29 Aug 2024 11:07:04 +0200 Subject: [PATCH 05/17] fix test --- pallets/vesting-mbm/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/vesting-mbm/src/mock.rs b/pallets/vesting-mbm/src/mock.rs index 61f83c08a..e245a971d 100644 --- a/pallets/vesting-mbm/src/mock.rs +++ b/pallets/vesting-mbm/src/mock.rs @@ -55,7 +55,7 @@ impl pallet_balances::Config for Runtime { } parameter_types! { - pub const MaxServiceWeight: Weight = Weight::MAX.div(10); + pub const MaxServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000); } #[derive_impl(pallet_migrations::config_preludes::TestDefaultConfig)] From 13c0d19fdde26791136d2d31194eebdf8b97ee34 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Thu, 29 Aug 2024 14:01:18 +0200 Subject: [PATCH 06/17] fix test --- pallets/vesting-mbm/src/mock.rs | 3 +++ pallets/vesting-mbm/src/tests.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pallets/vesting-mbm/src/mock.rs b/pallets/vesting-mbm/src/mock.rs index e245a971d..f562c71e5 100644 --- a/pallets/vesting-mbm/src/mock.rs +++ b/pallets/vesting-mbm/src/mock.rs @@ -60,7 +60,10 @@ parameter_types! { #[derive_impl(pallet_migrations::config_preludes::TestDefaultConfig)] impl pallet_migrations::Config for Runtime { + #[cfg(not(feature = "runtime-benchmarks"))] type Migrations = (crate::LazyMigration>,); + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; type MigrationStatusHandler = (); type MaxServiceWeight = MaxServiceWeight; } diff --git a/pallets/vesting-mbm/src/tests.rs b/pallets/vesting-mbm/src/tests.rs index 008daf3cd..052c18b69 100644 --- a/pallets/vesting-mbm/src/tests.rs +++ b/pallets/vesting-mbm/src/tests.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Astar. If not, see . -#![cfg(test)] +#![cfg(all(test, not(feature = "runtime-benchmarks")))] use crate::mock::{ new_test_ext, run_to_block, AllPalletsWithSystem, Balances, RuntimeOrigin, Vesting, ALICE, BOB, From 824da5ada5272f8a190acfe319383c7ec44f68a2 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 2 Sep 2024 10:35:36 +0200 Subject: [PATCH 07/17] enable async backing --- runtime/shibuya/src/lib.rs | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index c0d81cada..3d7d02b1d 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -147,7 +147,7 @@ pub const fn contracts_deposit(items: u32, bytes: u32) -> Balance { } /// Change this to adjust the block time. -pub const MILLISECS_PER_BLOCK: u64 = 12000; +pub const MILLISECS_PER_BLOCK: u64 = 6000; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; // Time is measured by number of blocks. @@ -157,7 +157,7 @@ pub const DAYS: BlockNumber = HOURS * 24; /// Maximum number of blocks simultaneously accepted by the Runtime, not yet included into the /// relay chain. -pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; +pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; /// How many parachain blocks are processed by the relay chain per parent. Limits the number of /// blocks authored per slot. pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; @@ -232,9 +232,9 @@ const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used /// by Operational extrinsics. const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); -/// We allow for 0.5 seconds of compute with a 6 second average block time. +/// We allow for 2 seconds of compute with a 6 second average block time. const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( - WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), + WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), polkadot_primitives::MAX_POV_SIZE as u64, ); @@ -332,15 +332,10 @@ impl frame_system::Config for Runtime { type PostTransactions = (); } -parameter_types! { - pub const MinimumPeriod: u64 = MILLISECS_PER_BLOCK / 2; -} - impl pallet_timestamp::Config for Runtime { - /// A timestamp: milliseconds since the unix epoch. type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; + type OnTimestampSet = Aura; + type MinimumPeriod = ConstU64<0>; type WeightInfo = pallet_timestamp::weights::SubstrateWeight; } @@ -572,8 +567,7 @@ impl pallet_aura::Config for Runtime { type DisabledValidators = (); type MaxAuthorities = ConstU32<250>; type SlotDuration = ConstU64; - // Set to `true` once async backing is enabled. - type AllowMultipleBlocksPerSlot = ConstBool; + type AllowMultipleBlocksPerSlot = ConstBool; } impl cumulus_pallet_aura_ext::Config for Runtime {} @@ -929,8 +923,8 @@ parameter_types! { /// max_gas_limit = max_tx_ref_time / WEIGHT_PER_GAS = max_pov_size * gas_limit_pov_size_ratio /// gas_limit_pov_size_ratio = ceil((max_tx_ref_time / WEIGHT_PER_GAS) / max_pov_size) /// - /// Equals 4 for values used by Shibuya runtime. - pub const GasLimitPovSizeRatio: u64 = 4; + /// Equals 16 for values used by Shibuya runtime. + pub const GasLimitPovSizeRatio: u64 = 16; } impl pallet_evm::Config for Runtime { @@ -1190,7 +1184,7 @@ parameter_types! { // Of course it's not true for Shibuya, but SBY is worthless, a test token. pub const NativeCurrencyId: CurrencyId = CurrencyId::ASTR; // Aggregate values for one day. - pub const AggregationDuration: BlockNumber = 7200; + pub const AggregationDuration: BlockNumber = DAYS; } impl pallet_price_aggregator::Config for Runtime { From 0e1d5db5a7e96c0730081606917c8c2f989f595d Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 2 Sep 2024 15:13:51 +0200 Subject: [PATCH 08/17] fix integration tests --- Cargo.lock | 2 ++ runtime/shibuya/src/lib.rs | 2 +- tests/integration/Cargo.toml | 2 ++ tests/integration/src/setup.rs | 64 ++++++++++++++++++++++++---------- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e7d03b64..936523ba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5579,6 +5579,7 @@ dependencies = [ "pallet-membership", "pallet-price-aggregator", "pallet-proxy", + "pallet-session", "pallet-timestamp", "pallet-unified-accounts", "pallet-utility", @@ -5587,6 +5588,7 @@ dependencies = [ "sha3", "shibuya-runtime", "shiden-runtime", + "sp-consensus-aura", "sp-core", "sp-io", "sp-runtime", diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 3d7d02b1d..f612535e2 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -204,7 +204,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("shibuya"), impl_name: create_runtime_str!("shibuya"), authoring_version: 1, - spec_version: 136, + spec_version: 137, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 3, diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index 19e075fc5..6ae0c9a9f 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -34,8 +34,10 @@ pallet-contracts-uapi = { workspace = true } pallet-democracy = { workspace = true } pallet-membership = { workspace = true } pallet-proxy = { workspace = true } +pallet-session = { workspace = true } pallet-timestamp = { workspace = true } pallet-utility = { workspace = true } +sp-consensus-aura = { workspace = true } sp-core = { workspace = true } sp-io = { workspace = true } sp-runtime = { workspace = true } diff --git a/tests/integration/src/setup.rs b/tests/integration/src/setup.rs index 8b555ae23..4976a6cdb 100644 --- a/tests/integration/src/setup.rs +++ b/tests/integration/src/setup.rs @@ -24,21 +24,21 @@ pub use frame_support::{ weights::Weight, }; use parity_scale_codec::Encode; -pub use sp_core::{Get, H160}; -pub use sp_runtime::{AccountId32, MultiAddress}; +pub use sp_core::{sr25519, Get, H160}; +pub use sp_runtime::{AccountId32, Digest, DigestItem, MultiAddress}; use cumulus_primitives_core::{relay_chain::HeadData, PersistedValidationData}; use cumulus_primitives_parachain_inherent::ParachainInherentData; use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder; +use sp_consensus_aura::{Slot, SlotDuration, AURA_ENGINE_ID}; +#[cfg(feature = "shibuya")] +pub use astar_primitives::governance::{ + CommunityCouncilMembershipInst, MainCouncilMembershipInst, TechnicalCommitteeMembershipInst, +}; pub use astar_primitives::{ - dapp_staking::CycleConfiguration, - governance::{ - CommunityCouncilMembershipInst, MainCouncilMembershipInst, OracleMembershipInst, - TechnicalCommitteeMembershipInst, - }, - oracle::Price, - BlockNumber, + dapp_staking::CycleConfiguration, genesis::GenesisAccount, governance::OracleMembershipInst, + oracle::Price, BlockNumber, }; #[cfg(feature = "shibuya")] @@ -105,11 +105,13 @@ pub const INITIAL_AMOUNT: u128 = 100_000 * UNIT; pub const INIT_PRICE: Price = Price::from_rational(1, 10); pub type SystemError = frame_system::Error; +use cumulus_pallet_parachain_system::RelaychainDataProvider; pub use pallet_balances::Call as BalancesCall; pub use pallet_dapp_staking as DappStakingCall; pub use pallet_proxy::Event as ProxyEvent; pub use pallet_utility::{Call as UtilityCall, Event as UtilityEvent}; use parity_scale_codec::Decode; +use sp_runtime::traits::BlockNumberProvider; pub struct ExtBuilder { balances: Vec<(AccountId32, Balance)>, @@ -138,6 +140,16 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); + as BuildStorage>::assimilate_storage( + &pallet_aura::GenesisConfig:: { + authorities: vec![GenesisAccount::::from_seed("Alice") + .pub_key() + .into()], + }, + &mut t, + ) + .unwrap(); + // Setup initial oracle members as BuildStorage>::assimilate_storage( &pallet_membership::GenesisConfig:: { @@ -193,7 +205,13 @@ impl ExtBuilder { let mut ext = sp_io::TestExternalities::new(t); ext.execute_with(|| { - System::set_block_number(1); + // Ensure the initial state is set for the first block + System::initialize(&1, &Default::default(), &Digest { + logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, Slot::from(1).encode())], + }); + AllPalletsWithoutSystem::on_initialize(1); + set_timestamp(); + set_validation_data(); let era_length = ::CycleConfiguration::blocks_per_era(); let voting_period_length_in_eras = @@ -210,11 +228,6 @@ impl ExtBuilder { maintenance: false, }); pallet_dapp_staking::Safeguard::::put(false); - - // Ensure the initial state is set for the first block - AllPalletsWithSystem::on_initialize(1); - set_timestamp(); - set_validation_data(); }); ext } @@ -238,20 +251,23 @@ fn set_timestamp() { } fn set_validation_data() { - let block_number = System::block_number(); let para_id = ::SelfParaId::get(); let parent_head = HeadData(b"deadbeef".into()); let sproof_builder = RelayStateSproofBuilder { para_id, included_para_head: Some(parent_head.clone()), + current_slot: Slot::from_timestamp( + pallet_timestamp::Now::::get().into(), + SlotDuration::from_millis(6_000), + ), ..Default::default() }; let (relay_parent_storage_root, relay_chain_state) = sproof_builder.into_state_root_and_proof(); let para_inherent_data = ParachainInherentData { validation_data: PersistedValidationData { parent_head, - relay_parent_number: block_number, + relay_parent_number: RelaychainDataProvider::::current_block_number() + 1, relay_parent_storage_root, max_pov_size: 5_000_000, }, @@ -286,8 +302,18 @@ pub fn run_to_block(n: BlockNumber) { ); // initialize block - System::set_block_number(block_number + 1); - AllPalletsWithSystem::on_initialize(block_number + 1); + let slot = Slot::from_timestamp( + (pallet_timestamp::Now::::get() + SLOT_DURATION).into(), + SlotDuration::from_millis(SLOT_DURATION), + ); + System::initialize( + &(block_number + 1), + &Default::default(), + &Digest { + logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())], + }, + ); + AllPalletsWithoutSystem::on_initialize(block_number + 1); // apply inherent set_timestamp(); set_validation_data(); From bcf8d8f2d747a2bf069d890bf35c8f1f70c4bb2f Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 2 Sep 2024 16:08:57 +0200 Subject: [PATCH 09/17] zepter --- tests/integration/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index 6ae0c9a9f..47426441f 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -123,6 +123,8 @@ std = [ "unified-accounts-chain-extension-types/std", "xcm/std", "xcm-fee-payment-runtime-api/std", + "pallet-session/std", + "sp-consensus-aura/std" ] shibuya = ["shibuya-runtime"] shiden = ["shiden-runtime"] From fa171f5cb4e9a6cc7568ae40f876a936a5ec3376 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 2 Sep 2024 16:15:56 +0200 Subject: [PATCH 10/17] revert spec change --- runtime/shibuya/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index f612535e2..3d7d02b1d 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -204,7 +204,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("shibuya"), impl_name: create_runtime_str!("shibuya"), authoring_version: 1, - spec_version: 137, + spec_version: 136, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 3, From 9a03163d6c1abdb01f2b94a6fa9f5f1785cdcde5 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 2 Sep 2024 16:53:13 +0200 Subject: [PATCH 11/17] taplo fmt --- tests/integration/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index 47426441f..2df214f42 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -124,7 +124,7 @@ std = [ "xcm/std", "xcm-fee-payment-runtime-api/std", "pallet-session/std", - "sp-consensus-aura/std" + "sp-consensus-aura/std", ] shibuya = ["shibuya-runtime"] shiden = ["shiden-runtime"] From c167ef9e433255bc2e15d51794b2e9cd0be4efcc Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Tue, 3 Sep 2024 16:01:05 +0200 Subject: [PATCH 12/17] dapp-staking mbm --- Cargo.lock | 1 + pallets/dapp-staking/Cargo.toml | 1 + pallets/dapp-staking/src/benchmarking/mod.rs | 69 +++++++++++++++- pallets/dapp-staking/src/migration.rs | 84 ++++++++++++++++++- pallets/dapp-staking/src/test/migrations.rs | 85 ++++++++++++++++++++ pallets/dapp-staking/src/test/mock.rs | 25 +++++- pallets/dapp-staking/src/test/mod.rs | 1 + pallets/dapp-staking/src/weights.rs | 9 +++ pallets/vesting-mbm/src/lib.rs | 5 +- runtime/shibuya/src/lib.rs | 9 ++- 10 files changed, 279 insertions(+), 10 deletions(-) create mode 100644 pallets/dapp-staking/src/test/migrations.rs diff --git a/Cargo.lock b/Cargo.lock index 936523ba9..277f1f1a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8487,6 +8487,7 @@ dependencies = [ "log", "num-traits", "pallet-balances", + "pallet-migrations", "parity-scale-codec", "scale-info", "serde", diff --git a/pallets/dapp-staking/Cargo.toml b/pallets/dapp-staking/Cargo.toml index 61d9ff225..bd8cdd709 100644 --- a/pallets/dapp-staking/Cargo.toml +++ b/pallets/dapp-staking/Cargo.toml @@ -29,6 +29,7 @@ frame-benchmarking = { workspace = true, optional = true } [dev-dependencies] pallet-balances = { workspace = true } +pallet-migrations = { workspace = true } [features] default = ["std"] diff --git a/pallets/dapp-staking/src/benchmarking/mod.rs b/pallets/dapp-staking/src/benchmarking/mod.rs index 0399a8d46..c8ec3ddef 100644 --- a/pallets/dapp-staking/src/benchmarking/mod.rs +++ b/pallets/dapp-staking/src/benchmarking/mod.rs @@ -21,7 +21,7 @@ use super::{Pallet as DappStaking, *}; use astar_primitives::Balance; use frame_benchmarking::v2::*; -use frame_support::assert_ok; +use frame_support::{assert_ok, migrations::SteppedMigration, weights::WeightMeter}; use frame_system::{Pallet as System, RawOrigin}; use sp_std::prelude::*; @@ -1070,6 +1070,73 @@ mod benchmarks { ); } + /// Benchmark a single step of mbm migration. + #[benchmark] + fn step() { + let alice: T::AccountId = account("alice", 0, 1); + + Ledger::::set( + &alice, + AccountLedger { + locked: 1000, + unlocking: vec![ + UnlockingChunk { + amount: 100, + unlock_block: 5, + }, + UnlockingChunk { + amount: 100, + unlock_block: 20, + }, + ] + .try_into() + .unwrap(), + staked: Default::default(), + staked_future: None, + contract_stake_count: 0, + }, + ); + CurrentEraInfo::::put(EraInfo { + total_locked: 1000, + unlocking: 200, + current_stake_amount: Default::default(), + next_stake_amount: Default::default(), + }); + + System::::set_block_number(10u32.into()); + let mut meter = WeightMeter::new(); + + #[block] + { + crate::migration::LazyMigration::>::step( + None, &mut meter, + ) + .unwrap(); + } + + assert_eq!( + Ledger::::get(&alice), + AccountLedger { + locked: 1000, + unlocking: vec![ + UnlockingChunk { + amount: 100, + unlock_block: 5, // already unlocked + }, + UnlockingChunk { + amount: 100, + unlock_block: 30, // double remaining blocks + }, + ] + .try_into() + .unwrap(), + staked: Default::default(), + staked_future: None, + contract_stake_count: 0, + } + ); + } + impl_benchmark_test_suite!( Pallet, crate::benchmarking::tests::new_test_ext(), diff --git a/pallets/dapp-staking/src/migration.rs b/pallets/dapp-staking/src/migration.rs index 35e27ccfb..2f0511ac8 100644 --- a/pallets/dapp-staking/src/migration.rs +++ b/pallets/dapp-staking/src/migration.rs @@ -17,7 +17,12 @@ // along with Astar. If not, see . use super::*; -use frame_support::{storage_alias, traits::UncheckedOnRuntimeUpgrade}; +use frame_support::{ + migrations::{MigrationId, SteppedMigration, SteppedMigrationError}, + storage_alias, + traits::UncheckedOnRuntimeUpgrade, + weights::WeightMeter, +}; #[cfg(feature = "try-runtime")] use sp_std::vec::Vec; @@ -412,3 +417,80 @@ pub mod v6 { pub period: PeriodNumber, } } + +const PALLET_MIGRATIONS_ID: &[u8; 16] = b"dapp-staking-mbm"; + +pub struct LazyMigration(PhantomData<(T, W)>); + +impl SteppedMigration for LazyMigration { + type Cursor = ::AccountId; + // Without the explicit length here the construction of the ID would not be infallible. + type Identifier = MigrationId<16>; + + /// The identifier of this migration. Which should be globally unique. + fn id() -> Self::Identifier { + MigrationId { + pallet_id: *PALLET_MIGRATIONS_ID, + version_from: 0, + version_to: 1, + } + } + + fn step( + mut cursor: Option, + meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + let required = W::step(); + // If there is not enough weight for a single step, return an error. This case can be + // problematic if it is the first migration that ran in this block. But there is nothing + // that we can do about it here. + if meter.remaining().any_lt(required) { + return Err(SteppedMigrationError::InsufficientWeight { required }); + } + + let mut count = 0u32; + let current_block_number = + frame_system::Pallet::::block_number().saturated_into::(); + + // We loop here to do as much progress as possible per step. + loop { + if meter.try_consume(required).is_err() { + break; + } + + let mut iter = if let Some(last_key) = cursor { + // If a cursor is provided, start iterating from the stored value + // corresponding to the last key processed in the previous step. + // Note that this only works if the old and the new map use the same way to hash + // storage keys. + Ledger::::iter_from(Ledger::::hashed_key_for(last_key)) + } else { + // If no cursor is provided, start iterating from the beginning. + Ledger::::iter() + }; + + // If there's a next item in the iterator, perform the migration. + if let Some((ref last_key, mut ledger)) = iter.next() { + for chunk in ledger.unlocking.iter_mut() { + let remaining_blocks = chunk.unlock_block.saturating_sub(current_block_number); + chunk.unlock_block.saturating_accrue(remaining_blocks); + } + + // Override ledger + Ledger::::insert(last_key, ledger); + + // inc counter + count.saturating_inc(); + + // Return the processed key as the new cursor. + cursor = Some(last_key.clone()) + } else { + // Signal that the migration is complete (no more items to process). + cursor = None; + break; + } + } + log::debug!(target: LOG_TARGET, "migrated {count:?} entries"); + Ok(cursor) + } +} diff --git a/pallets/dapp-staking/src/test/migrations.rs b/pallets/dapp-staking/src/test/migrations.rs new file mode 100644 index 000000000..d1e1109ac --- /dev/null +++ b/pallets/dapp-staking/src/test/migrations.rs @@ -0,0 +1,85 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +#![cfg(all(test, not(feature = "runtime-benchmarks")))] + +use crate::test::mock::*; +use crate::{AccountLedger, CurrentEraInfo, EraInfo, Ledger, UnlockingChunk}; +use frame_support::traits::OnRuntimeUpgrade; + +#[test] +fn lazy_migrations() { + ExtBuilder::default().build_and_execute(|| { + Ledger::::set( + &1, + AccountLedger { + locked: 1000, + unlocking: vec![ + UnlockingChunk { + amount: 100, + unlock_block: 5, + }, + UnlockingChunk { + amount: 100, + unlock_block: 20, + }, + ] + .try_into() + .unwrap(), + staked: Default::default(), + staked_future: None, + contract_stake_count: 0, + }, + ); + CurrentEraInfo::::put(EraInfo { + total_locked: 1000, + unlocking: 200, + current_stake_amount: Default::default(), + next_stake_amount: Default::default(), + }); + + // go to block before migration + run_to_block(9); + + // onboard MBMs + AllPalletsWithSystem::on_runtime_upgrade(); + run_to_block(10); + + assert_eq!( + Ledger::::get(&1), + AccountLedger { + locked: 1000, + unlocking: vec![ + UnlockingChunk { + amount: 100, + unlock_block: 5, // already unlocked + }, + UnlockingChunk { + amount: 100, + unlock_block: 30, // double remaining blocks + }, + ] + .try_into() + .unwrap(), + staked: Default::default(), + staked_future: None, + contract_stake_count: 0, + } + ); + }) +} diff --git a/pallets/dapp-staking/src/test/mock.rs b/pallets/dapp-staking/src/test/mock.rs index 8fc568c95..1a1b1532c 100644 --- a/pallets/dapp-staking/src/test/mock.rs +++ b/pallets/dapp-staking/src/test/mock.rs @@ -23,7 +23,9 @@ use crate::{ }; use frame_support::{ - construct_runtime, ord_parameter_types, parameter_types, + construct_runtime, derive_impl, + migrations::MultiStepMigrator, + ord_parameter_types, parameter_types, traits::{fungible::Mutate as FunMutate, ConstBool, ConstU128, ConstU32, EitherOfDiverse}, weights::Weight, }; @@ -54,6 +56,7 @@ construct_runtime!( System: frame_system, Balances: pallet_balances, DappStaking: pallet_dapp_staking, + MultiBlockMigrations: pallet_migrations, } ); @@ -89,7 +92,7 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; type RuntimeTask = RuntimeTask; type SingleBlockMigrations = (); - type MultiBlockMigrator = (); + type MultiBlockMigrator = MultiBlockMigrations; type PreInherents = (); type PostInherents = (); type PostTransactions = (); @@ -111,6 +114,21 @@ impl pallet_balances::Config for Test { type WeightInfo = (); } +parameter_types! { + pub const MaxServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000); +} + +#[derive_impl(pallet_migrations::config_preludes::TestDefaultConfig)] +impl pallet_migrations::Config for Test { + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = + (crate::migration::LazyMigration>,); + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type MigrationStatusHandler = (); + type MaxServiceWeight = MaxServiceWeight; +} + pub struct DummyPriceProvider; impl PriceProvider for DummyPriceProvider { fn average_price() -> FixedU128 { @@ -397,6 +415,9 @@ pub(crate) fn run_to_block(n: BlockNumber) { System::set_block_number(System::block_number() + 1); // This is performed outside of dapps staking but we expect it before on_initialize + // Done by Executive: + ::MultiBlockMigrator::step(); + let pre_snapshot = MemorySnapshot::new(); DappStaking::on_initialize(System::block_number()); assert_block_bump(&pre_snapshot); diff --git a/pallets/dapp-staking/src/test/mod.rs b/pallets/dapp-staking/src/test/mod.rs index f5baecd0a..7c891a6b2 100644 --- a/pallets/dapp-staking/src/test/mod.rs +++ b/pallets/dapp-staking/src/test/mod.rs @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Astar. If not, see . +mod migrations; pub(crate) mod mock; mod testing_utils; mod tests; diff --git a/pallets/dapp-staking/src/weights.rs b/pallets/dapp-staking/src/weights.rs index f7c46df53..d1303b718 100644 --- a/pallets/dapp-staking/src/weights.rs +++ b/pallets/dapp-staking/src/weights.rs @@ -73,6 +73,7 @@ pub trait WeightInfo { fn on_initialize_build_and_earn_to_build_and_earn() -> Weight; fn dapp_tier_assignment(x: u32, ) -> Weight; fn on_idle_cleanup() -> Weight; + fn step() -> Weight; } /// Weights for pallet_dapp_staking using the Substrate node and recommended hardware. @@ -477,6 +478,10 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + + fn step() -> Weight { + Weight::default() + } } // For backwards compatibility and tests @@ -880,4 +885,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } + + fn step() -> Weight { + Weight::default() + } } diff --git a/pallets/vesting-mbm/src/lib.rs b/pallets/vesting-mbm/src/lib.rs index 41b926d34..e2e02b313 100644 --- a/pallets/vesting-mbm/src/lib.rs +++ b/pallets/vesting-mbm/src/lib.rs @@ -42,10 +42,7 @@ const PALLET_MIGRATIONS_ID: &[u8; 18] = b"pallet-vesting-mbm"; pub struct LazyMigration(core::marker::PhantomData<(T, W)>); -impl SteppedMigration for LazyMigration -where - T: frame_system::Config + pallet_vesting::Config, -{ +impl SteppedMigration for LazyMigration { type Cursor = ::AccountId; // Without the explicit length here the construction of the ID would not be infallible. type Identifier = MigrationId<18>; diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 3d7d02b1d..0aeeb6e47 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -1518,8 +1518,13 @@ parameter_types! { impl pallet_migrations::Config for Runtime { type RuntimeEvent = RuntimeEvent; #[cfg(not(feature = "runtime-benchmarks"))] - type Migrations = - (vesting_mbm::LazyMigration>,); + type Migrations = ( + pallet_dapp_staking::migration::LazyMigration< + Runtime, + pallet_dapp_staking::weights::SubstrateWeight, + >, + vesting_mbm::LazyMigration>, + ); // Benchmarks need mocked migrations to guarantee that they succeed. #[cfg(feature = "runtime-benchmarks")] type Migrations = pallet_migrations::mock_helpers::MockedMigrations; From d308490ec6fba7647e86e772a97df663549039dc Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Tue, 3 Sep 2024 16:18:15 +0200 Subject: [PATCH 13/17] weight step method --- runtime/astar/src/weights/pallet_dapp_staking.rs | 4 ++++ runtime/shibuya/src/weights/pallet_dapp_staking.rs | 4 ++++ runtime/shiden/src/weights/pallet_dapp_staking.rs | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/runtime/astar/src/weights/pallet_dapp_staking.rs b/runtime/astar/src/weights/pallet_dapp_staking.rs index 6bb3456bb..a180f9446 100644 --- a/runtime/astar/src/weights/pallet_dapp_staking.rs +++ b/runtime/astar/src/weights/pallet_dapp_staking.rs @@ -467,4 +467,8 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + + fn step() -> Weight { + Weight::default() + } } diff --git a/runtime/shibuya/src/weights/pallet_dapp_staking.rs b/runtime/shibuya/src/weights/pallet_dapp_staking.rs index 1b2808c35..d3b22b8dc 100644 --- a/runtime/shibuya/src/weights/pallet_dapp_staking.rs +++ b/runtime/shibuya/src/weights/pallet_dapp_staking.rs @@ -467,4 +467,8 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + + fn step() -> Weight { + Weight::default() + } } diff --git a/runtime/shiden/src/weights/pallet_dapp_staking.rs b/runtime/shiden/src/weights/pallet_dapp_staking.rs index 9ccd24fab..cdebd7a4f 100644 --- a/runtime/shiden/src/weights/pallet_dapp_staking.rs +++ b/runtime/shiden/src/weights/pallet_dapp_staking.rs @@ -467,4 +467,8 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + + fn step() -> Weight { + Weight::default() + } } From 270c5dacba3e860084b3cccec5809bbc3815bdc3 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Tue, 3 Sep 2024 17:15:07 +0200 Subject: [PATCH 14/17] update weights --- pallets/dapp-staking/src/weights.rs | 22 +++++++++++++++---- .../astar/src/weights/pallet_dapp_staking.rs | 11 ++++++++-- .../src/weights/pallet_dapp_staking.rs | 11 ++++++++-- .../shiden/src/weights/pallet_dapp_staking.rs | 11 ++++++++-- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/pallets/dapp-staking/src/weights.rs b/pallets/dapp-staking/src/weights.rs index d1303b718..31859fc35 100644 --- a/pallets/dapp-staking/src/weights.rs +++ b/pallets/dapp-staking/src/weights.rs @@ -478,9 +478,16 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - + /// Storage: `DappStaking::Ledger` (r:2 w:1) + /// Proof: `DappStaking::Ledger` (`max_values`: None, `max_size`: Some(310), added: 2785, mode: `MaxEncodedLen`) fn step() -> Weight { - Weight::default() + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `6560` + // Minimum execution time: 10_060_000 picoseconds. + Weight::from_parts(10_314_000, 6560) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } @@ -885,8 +892,15 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - + /// Storage: `DappStaking::Ledger` (r:2 w:1) + /// Proof: `DappStaking::Ledger` (`max_values`: None, `max_size`: Some(310), added: 2785, mode: `MaxEncodedLen`) fn step() -> Weight { - Weight::default() + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `6560` + // Minimum execution time: 10_060_000 picoseconds. + Weight::from_parts(10_314_000, 6560) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/runtime/astar/src/weights/pallet_dapp_staking.rs b/runtime/astar/src/weights/pallet_dapp_staking.rs index a180f9446..29b26bbff 100644 --- a/runtime/astar/src/weights/pallet_dapp_staking.rs +++ b/runtime/astar/src/weights/pallet_dapp_staking.rs @@ -467,8 +467,15 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - + /// Storage: `DappStaking::Ledger` (r:2 w:1) + /// Proof: `DappStaking::Ledger` (`max_values`: None, `max_size`: Some(310), added: 2785, mode: `MaxEncodedLen`) fn step() -> Weight { - Weight::default() + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `6560` + // Minimum execution time: 10_060_000 picoseconds. + Weight::from_parts(10_314_000, 6560) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/runtime/shibuya/src/weights/pallet_dapp_staking.rs b/runtime/shibuya/src/weights/pallet_dapp_staking.rs index d3b22b8dc..e10cd8d18 100644 --- a/runtime/shibuya/src/weights/pallet_dapp_staking.rs +++ b/runtime/shibuya/src/weights/pallet_dapp_staking.rs @@ -467,8 +467,15 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - + /// Storage: `DappStaking::Ledger` (r:2 w:1) + /// Proof: `DappStaking::Ledger` (`max_values`: None, `max_size`: Some(310), added: 2785, mode: `MaxEncodedLen`) fn step() -> Weight { - Weight::default() + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `6560` + // Minimum execution time: 10_060_000 picoseconds. + Weight::from_parts(10_314_000, 6560) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/runtime/shiden/src/weights/pallet_dapp_staking.rs b/runtime/shiden/src/weights/pallet_dapp_staking.rs index cdebd7a4f..169284360 100644 --- a/runtime/shiden/src/weights/pallet_dapp_staking.rs +++ b/runtime/shiden/src/weights/pallet_dapp_staking.rs @@ -467,8 +467,15 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - + /// Storage: `DappStaking::Ledger` (r:2 w:1) + /// Proof: `DappStaking::Ledger` (`max_values`: None, `max_size`: Some(310), added: 2785, mode: `MaxEncodedLen`) fn step() -> Weight { - Weight::default() + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `6560` + // Minimum execution time: 10_060_000 picoseconds. + Weight::from_parts(10_314_000, 6560) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } From f594d619ab30dae8de4b43532a8f3543bfc50e5f Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Wed, 4 Sep 2024 11:49:53 +0200 Subject: [PATCH 15/17] skip accounts without locked --- pallets/dapp-staking/src/migration.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pallets/dapp-staking/src/migration.rs b/pallets/dapp-staking/src/migration.rs index 2f0511ac8..43c1999d3 100644 --- a/pallets/dapp-staking/src/migration.rs +++ b/pallets/dapp-staking/src/migration.rs @@ -471,7 +471,15 @@ impl SteppedMigration for LazyMigration { // If there's a next item in the iterator, perform the migration. if let Some((ref last_key, mut ledger)) = iter.next() { + if ledger.unlocking.is_empty() { + // no unlocking for this account, nothing to update + cursor = Some(last_key.clone()); // Return the processed key as the new cursor. + continue; + } for chunk in ledger.unlocking.iter_mut() { + if current_block_number >= chunk.unlock_block { + continue; // chunk already unlocked + } let remaining_blocks = chunk.unlock_block.saturating_sub(current_block_number); chunk.unlock_block.saturating_accrue(remaining_blocks); } From 22abf1a8c2dfba043af0800efa0f808d456aa80c Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Wed, 4 Sep 2024 19:42:40 +0200 Subject: [PATCH 16/17] next_era_start and block_reward adjusment --- pallets/dapp-staking/src/migration.rs | 33 ++++++++++++++++++---- pallets/inflation/src/lib.rs | 1 + pallets/inflation/src/migration.rs | 39 ++++++++++++++++++++++++++ runtime/shibuya/src/lib.rs | 40 ++------------------------- 4 files changed, 70 insertions(+), 43 deletions(-) create mode 100644 pallets/inflation/src/migration.rs diff --git a/pallets/dapp-staking/src/migration.rs b/pallets/dapp-staking/src/migration.rs index 43c1999d3..f782110e2 100644 --- a/pallets/dapp-staking/src/migration.rs +++ b/pallets/dapp-staking/src/migration.rs @@ -20,7 +20,7 @@ use super::*; use frame_support::{ migrations::{MigrationId, SteppedMigration, SteppedMigrationError}, storage_alias, - traits::UncheckedOnRuntimeUpgrade, + traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade}, weights::WeightMeter, }; @@ -449,6 +449,7 @@ impl SteppedMigration for LazyMigration { } let mut count = 0u32; + let mut migrated = 0u32; let current_block_number = frame_system::Pallet::::block_number().saturated_into::(); @@ -471,9 +472,13 @@ impl SteppedMigration for LazyMigration { // If there's a next item in the iterator, perform the migration. if let Some((ref last_key, mut ledger)) = iter.next() { + // inc count + count.saturating_inc(); + if ledger.unlocking.is_empty() { // no unlocking for this account, nothing to update - cursor = Some(last_key.clone()); // Return the processed key as the new cursor. + // Return the processed key as the new cursor. + cursor = Some(last_key.clone()); continue; } for chunk in ledger.unlocking.iter_mut() { @@ -487,8 +492,8 @@ impl SteppedMigration for LazyMigration { // Override ledger Ledger::::insert(last_key, ledger); - // inc counter - count.saturating_inc(); + // inc migrated + migrated.saturating_inc(); // Return the processed key as the new cursor. cursor = Some(last_key.clone()) @@ -498,7 +503,25 @@ impl SteppedMigration for LazyMigration { break; } } - log::debug!(target: LOG_TARGET, "migrated {count:?} entries"); + log::info!(target: LOG_TARGET, "🚚 iterated {count} entries, migrated {migrated}"); Ok(cursor) } } + +/// Double the remaining block for next era start +pub struct AdjustEraMigration(PhantomData); + +impl OnRuntimeUpgrade for AdjustEraMigration { + fn on_runtime_upgrade() -> Weight { + log::info!("🚚 migrated to async backing, adjust next era start"); + ActiveProtocolState::::mutate_exists(|maybe| { + if let Some(state) = maybe { + let current_block_number = + frame_system::Pallet::::block_number().saturated_into::(); + let remaining = state.next_era_start.saturating_sub(current_block_number); + state.next_era_start.saturating_accrue(2 * remaining); + } + }); + T::DbWeight::get().reads_writes(1, 1) + } +} diff --git a/pallets/inflation/src/lib.rs b/pallets/inflation/src/lib.rs index 25fa4bd50..c9baf754a 100644 --- a/pallets/inflation/src/lib.rs +++ b/pallets/inflation/src/lib.rs @@ -126,6 +126,7 @@ pub use weights::WeightInfo; #[cfg(any(feature = "runtime-benchmarks"))] pub mod benchmarking; +pub mod migration; #[cfg(test)] mod mock; #[cfg(test)] diff --git a/pallets/inflation/src/migration.rs b/pallets/inflation/src/migration.rs new file mode 100644 index 000000000..100b75a16 --- /dev/null +++ b/pallets/inflation/src/migration.rs @@ -0,0 +1,39 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar 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. + +// Astar 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 Astar. If not, see . + +use super::*; +use frame_support::pallet_prelude::Weight; +use frame_support::traits::OnRuntimeUpgrade; + +/// Half block reward for collators and treasury +pub struct AdjustBlockRewardMigration(core::marker::PhantomData); + +impl OnRuntimeUpgrade for AdjustBlockRewardMigration { + fn on_runtime_upgrade() -> Weight { + log::info!("🚚 migrated to async backing, adjust reward per block"); + ActiveInflationConfig::::mutate_exists(|maybe| { + if let Some(config) = maybe { + config.collator_reward_per_block = + config.collator_reward_per_block.saturating_div(2); + config.treasury_reward_per_block = + config.treasury_reward_per_block.saturating_div(2); + } + }); + T::DbWeight::get().reads_writes(1, 1) + } +} diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 0aeeb6e47..cd05f7511 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -1646,33 +1646,6 @@ pub type Executive = frame_executive::Executive< Migrations, >; -parameter_types! { - // Threshold amount variation allowed for this migration - 150% - pub const ThresholdVariationPercentage: u32 = 150; - // percentages below are calculated based on a total issuance at the time when dApp staking v3 was launched (147M) - pub const TierThresholds: [TierThreshold; 4] = [ - TierThreshold::DynamicPercentage { - percentage: Perbill::from_parts(20_000), // 0.0020% - minimum_required_percentage: Perbill::from_parts(17_000), // 0.0017% - }, - TierThreshold::DynamicPercentage { - percentage: Perbill::from_parts(13_000), // 0.0013% - minimum_required_percentage: Perbill::from_parts(10_000), // 0.0010% - }, - TierThreshold::DynamicPercentage { - percentage: Perbill::from_parts(5_400), // 0.00054% - minimum_required_percentage: Perbill::from_parts(3_400), // 0.00034% - }, - TierThreshold::FixedPercentage { - required_percentage: Perbill::from_parts(1_400), // 0.00014% - }, - ]; -} - -parameter_types! { - pub const DmpQueuePalletName: &'static str = "DmpQueue"; -} - /// All migrations that will run on the next runtime upgrade. /// /// __NOTE:__ THE ORDER IS IMPORTANT. @@ -1680,17 +1653,8 @@ pub type Migrations = (Unreleased, Permanent); /// Unreleased migrations. Add new ones here: pub type Unreleased = ( - // dApp-staking dyn tier threshold migrations - pallet_dapp_staking::migration::versioned_migrations::V7ToV8< - Runtime, - TierThresholds, - ThresholdVariationPercentage, - >, - frame_support::migrations::RemovePallet< - DmpQueuePalletName, - ::DbWeight, - >, - pallet_contracts::Migration, + pallet_dapp_staking::migration::AdjustEraMigration, + pallet_inflation::migration::AdjustBlockRewardMigration, ); /// Migrations/checks that do not need to be versioned and can run on every upgrade. From 78dd7f921ae7d87d68579ebec16e8e9328b9534b Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Thu, 5 Sep 2024 08:56:25 +0200 Subject: [PATCH 17/17] fix migration --- pallets/dapp-staking/src/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/dapp-staking/src/migration.rs b/pallets/dapp-staking/src/migration.rs index f782110e2..79fa7e858 100644 --- a/pallets/dapp-staking/src/migration.rs +++ b/pallets/dapp-staking/src/migration.rs @@ -519,7 +519,7 @@ impl OnRuntimeUpgrade for AdjustEraMigration { let current_block_number = frame_system::Pallet::::block_number().saturated_into::(); let remaining = state.next_era_start.saturating_sub(current_block_number); - state.next_era_start.saturating_accrue(2 * remaining); + state.next_era_start.saturating_accrue(remaining); } }); T::DbWeight::get().reads_writes(1, 1)