Skip to content

Commit

Permalink
Asynchronous block generation adaption (#1628)
Browse files Browse the repository at this point in the history
* Modify the way current_block_number is obtained in the salp and vtokenvoting pallets.

* bifrost_parachain_staking: adapt MinBlocksPerRound

* bifrost_parachain_staking: Round storage migration

* bifrost_vtoken_voting: adapt ReferendumCheckInterval

* bifrost_vtoken_voting: VoteLockingPeriod and UndecidingTimeout storage migration

* fix clippy

* bifrost_vtoken_voting: ReferendumTimeoutV3 storage migration

* pallet_referenda: ReferendumInfoFor storage migration

---------

Co-authored-by: Edwin <[email protected]>
  • Loading branch information
SunTiebing and ark930 authored Feb 6, 2025
1 parent a7f050f commit 754e2b0
Show file tree
Hide file tree
Showing 12 changed files with 261 additions and 26 deletions.
2 changes: 2 additions & 0 deletions pallets/parachain-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,12 @@ pub mod pallet {
types::*,
InflationInfo, Range, WeightInfo,
};
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);

/// Pallet for parachain staking
#[pallet::pallet]
#[pallet::without_storage_info]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(PhantomData<T>);

pub type RoundIndex = u32;
Expand Down
44 changes: 44 additions & 0 deletions pallets/parachain-staking/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,3 +583,47 @@ impl<T: Config> OnRuntimeUpgrade for RemoveDelegatorReserveToLockAndCollatorRese
Ok(())
}
}

pub mod v1 {
use super::*;
use crate::{Config, Pallet};
use frame_support::{pallet_prelude::StorageVersion, traits::OnRuntimeUpgrade};

pub struct MigrateToV1<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
fn on_runtime_upgrade() -> Weight {
if StorageVersion::get::<Pallet<T>>() < 1 {
log::info!("Migrating parachain-staking storage to v1");

Round::<T>::mutate(|round_info| {
round_info.length = round_info.length.saturating_mul(2);
});

StorageVersion::new(1).put::<Pallet<T>>();
Weight::from(T::DbWeight::get().reads_writes(1, 1))
} else {
log::warn!("parachain-staking migration should be removed.");
T::DbWeight::get().reads(1)
}
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::DispatchError> {
log::info!(
"parachain-staking before migration: version: {:?}",
StorageVersion::get::<Pallet<T>>(),
);

Ok(Vec::new())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
log::info!(
"parachain-staking after migration: version: {:?}",
StorageVersion::get::<Pallet<T>>(),
);
Ok(())
}
}
}
12 changes: 9 additions & 3 deletions pallets/salp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ pub mod pallet {
currency::TransferAll, MultiCurrency, MultiLockableCurrency, MultiReservableCurrency,
};
use sp_arithmetic::Percent;
use sp_runtime::traits::BlockNumberProvider;
use sp_std::{convert::TryInto, prelude::*};

#[pallet::config]
Expand Down Expand Up @@ -169,6 +170,8 @@ pub mod pallet {
type StablePool: StablePoolHandler<Balance = BalanceOf<Self>, AccountId = Self::AccountId>;

type VtokenMinting: VtokenMintingInterface<Self::AccountId, CurrencyId, BalanceOf<Self>>;
/// The current block number provider.
type BlockNumberProvider: BlockNumberProvider<BlockNumber = BlockNumberFor<Self>>;
}

#[pallet::pallet]
Expand Down Expand Up @@ -597,7 +600,7 @@ pub mod pallet {
RedeemPool::<T>::get() >= value,
Error::<T>::NotEnoughBalanceInRedeemPool
);
let cur_block = <frame_system::Pallet<T>>::block_number();
let cur_block = T::BlockNumberProvider::current_block_number();
let expired = Self::is_expired(cur_block, fund.last_slot)?;
ensure!(!expired, Error::<T>::VSBondExpired);
T::MultiCurrency::ensure_can_withdraw(vs_token, &who, value)
Expand Down Expand Up @@ -770,9 +773,12 @@ pub mod pallet {

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(n: BlockNumberFor<T>) -> Weight {
fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
let current_block = T::BlockNumberProvider::current_block_number();
// Release x% KSM/DOT from redeem-pool to bancor-pool per cycle
if n != Zero::zero() && (n % T::ReleaseCycle::get()) == Zero::zero() {
if current_block != Zero::zero()
&& (current_block % T::ReleaseCycle::get()) == Zero::zero()
{
if let Ok(rp_balance) = TryInto::<u128>::try_into(RedeemPool::<T>::get()) {
// Calculate the release amount
let release_amount = T::ReleaseRatio::get() * rp_balance;
Expand Down
20 changes: 9 additions & 11 deletions pallets/vtoken-voting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub mod pallet {
use frame_support::traits::CallerTrait;

/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(4);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(5);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
Expand Down Expand Up @@ -449,7 +449,7 @@ pub mod pallet {
>;

#[pallet::storage]
pub type ReferendumTimeoutV2<T: Config> = StorageDoubleMap<
pub type ReferendumTimeoutV3<T: Config> = StorageDoubleMap<
_,
Twox64Concat,
CurrencyIdOf<T>,
Expand Down Expand Up @@ -510,10 +510,8 @@ pub mod pallet {

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_idle(
bifrost_current_block_number: BlockNumberFor<T>,
remaining_weight: Weight,
) -> Weight {
fn on_idle(_n: BlockNumberFor<T>, remaining_weight: Weight) -> Weight {
let bifrost_current_block_number = T::LocalBlockNumberProvider::current_block_number();
let db_weight = T::DbWeight::get();
let mut used_weight = db_weight.reads(3);
if remaining_weight.any_lt(used_weight)
Expand All @@ -524,9 +522,9 @@ pub mod pallet {
let relay_current_block_number =
T::RelaychainBlockNumberProvider::current_block_number();

for (vtoken, time_out_block_number) in ReferendumTimeoutV2::<T>::iter_keys() {
for (vtoken, time_out_block_number) in ReferendumTimeoutV3::<T>::iter_keys() {
let referendum_timeout_list =
ReferendumTimeoutV2::<T>::get(vtoken, time_out_block_number);
ReferendumTimeoutV3::<T>::get(vtoken, time_out_block_number);
let len = referendum_timeout_list.len() as u64;
let temp_weight = db_weight.reads_writes(len, len) + db_weight.writes(1);
if remaining_weight.any_lt(used_weight + temp_weight) {
Expand Down Expand Up @@ -989,7 +987,7 @@ pub mod pallet {
if let ReferendumInfo::Ongoing(status) = info {
let current_block_number = Self::get_agent_block_number(&vtoken)?;
status.submitted = Some(current_block_number);
ReferendumTimeoutV2::<T>::mutate(
ReferendumTimeoutV3::<T>::mutate(
vtoken,
current_block_number.saturating_add(
UndecidingTimeout::<T>::get(vtoken)
Expand Down Expand Up @@ -1117,7 +1115,7 @@ pub mod pallet {
extra_fee: BalanceOf<T>,
f: impl FnOnce(QueryId) -> (),
) -> DispatchResult {
let now = frame_system::Pallet::<T>::block_number();
let now = T::LocalBlockNumberProvider::current_block_number();
let timeout = now.saturating_add(T::QueryTimeout::get());
let notify_runtime_call = <T as Config>::RuntimeCall::from(notify_call);
let notify_call_weight = notify_runtime_call.get_dispatch_info().weight;
Expand Down Expand Up @@ -1657,7 +1655,7 @@ pub mod pallet {
None => {}
});
}
ReferendumTimeoutV2::<T>::remove(vtoken, time_out_block_number);
ReferendumTimeoutV3::<T>::remove(vtoken, time_out_block_number);
}

/// This function checks whether the user's tokens can be unlocked early based on their vote status
Expand Down
86 changes: 85 additions & 1 deletion pallets/vtoken-voting/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,17 @@ pub mod v4 {
use frame_support::{pallet_prelude::StorageVersion, traits::OnRuntimeUpgrade};
use sp_runtime::traits::Get;

#[storage_alias]
pub type ReferendumTimeoutV2<T: Config> = StorageDoubleMap<
Pallet<T>,
Twox64Concat,
CurrencyIdOf<T>,
Twox64Concat,
BlockNumberFor<T>,
BoundedVec<PollIndex, ConstU32<256>>,
ValueQuery,
>;

pub struct MigrateToV4<T, C>(
sp_std::marker::PhantomData<T>,
sp_std::marker::PhantomData<C>,
Expand Down Expand Up @@ -313,7 +324,7 @@ pub fn migrate_to_v4<T: Config, C: Get<CurrencyIdOf<T>>>() -> Weight {
pool_index_vec.try_push(poll_index).unwrap();
}
// Insert into the new storage
ReferendumTimeoutV2::<T>::insert(vtoken, block_number, pool_index_vec);
v4::ReferendumTimeoutV2::<T>::insert(vtoken, block_number, pool_index_vec);
weight += T::DbWeight::get().reads_writes(0, 1);
});

Expand All @@ -333,3 +344,76 @@ pub fn migrate_to_v4<T: Config, C: Get<CurrencyIdOf<T>>>() -> Weight {

weight
}

pub mod v5 {
use super::*;
use crate::{Config, Pallet};
use cumulus_primitives_core::Weight;
use frame_support::{pallet_prelude::StorageVersion, traits::OnRuntimeUpgrade};

pub struct MigrateToV5<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for MigrateToV5<T> {
fn on_runtime_upgrade() -> Weight {
if StorageVersion::get::<Pallet<T>>() == 4 {
let weight_consumed = migrate_to_v5::<T>();
log::info!("Migrating vtoken-voting storage to v5");
StorageVersion::new(5).put::<Pallet<T>>();
weight_consumed
} else {
log::warn!("vtoken-voting migration should be removed.");
T::DbWeight::get().reads(1)
}
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::DispatchError> {
log::info!(
"vtoken-voting before migration: version: {:?}",
StorageVersion::get::<Pallet<T>>(),
);

Ok(Vec::new())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
log::info!(
"vtoken-voting after migration: version: {:?}",
StorageVersion::get::<Pallet<T>>(),
);

Ok(())
}
}
}

pub fn migrate_to_v5<T: Config>() -> Weight {
let mut weight: Weight = Weight::zero();
let current_block_number = T::LocalBlockNumberProvider::current_block_number();

VoteLockingPeriod::<T>::iter().for_each(|(currency_id, _)| {
if currency_id == VBNC {
VoteLockingPeriod::<T>::insert(currency_id, BlockNumberFor::<T>::from(14400u32));
weight += T::DbWeight::get().writes(1);
}
});

UndecidingTimeout::<T>::iter().for_each(|(currency_id, _)| {
if currency_id == VBNC {
UndecidingTimeout::<T>::insert(currency_id, BlockNumberFor::<T>::from(201600u32));
weight += T::DbWeight::get().writes(1);
}
});

v4::ReferendumTimeoutV2::<T>::iter().for_each(|(currency_id, block_number, value)| {
let new_block_number = if currency_id == VBNC {
block_number.saturating_sub(current_block_number) + block_number
} else {
block_number
};
ReferendumTimeoutV3::<T>::insert(currency_id, new_block_number, value);
weight += T::DbWeight::get().reads_writes(1, 1);
});

weight
}
2 changes: 1 addition & 1 deletion pallets/vtoken-voting/src/tests/kusama_common_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,7 @@ fn on_idle_works() {
let mut actual_count = 0;
for poll_index in 0..50 {
let relay_block_number = poll_index as BlockNumber;
if ReferendumTimeoutV2::<Runtime>::get(
if ReferendumTimeoutV3::<Runtime>::get(
vtoken,
relay_block_number + UndecidingTimeout::<Runtime>::get(vtoken).unwrap(),
)
Expand Down
2 changes: 1 addition & 1 deletion pallets/vtoken-voting/src/tests/polkadot_common_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,7 @@ fn on_idle_works() {
let mut actual_count = 0;
for poll_index in 0..50 {
let relay_block_number = poll_index as BlockNumber;
if ReferendumTimeoutV2::<Runtime>::get(
if ReferendumTimeoutV3::<Runtime>::get(
vtoken,
relay_block_number + UndecidingTimeout::<Runtime>::get(vtoken).unwrap(),
)
Expand Down
11 changes: 8 additions & 3 deletions runtime/bifrost-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,8 +808,8 @@ impl parachain_info::Config for Runtime {}
impl cumulus_pallet_aura_ext::Config for Runtime {}

parameter_types! {
/// Minimum round length is 2 minutes (10 * 12 second block times)
pub const MinBlocksPerRound: u32 = 10;
/// Minimum round length is 2 minutes
pub const MinBlocksPerRound: u32 = 2 * MINUTES;
/// Rounds before the collator leaving the candidates request can be executed
pub const LeaveCandidatesDelay: u32 = 84;
/// Rounds before the candidate bond increase/decrease can be executed
Expand Down Expand Up @@ -1084,6 +1084,7 @@ impl bifrost_salp::Config for Runtime {
type CurrencyIdRegister = AssetIdMaps<Runtime>;
type StablePool = StablePool;
type VtokenMinting = VtokenMinting;
type BlockNumberProvider = System;
}

parameter_types! {
Expand Down Expand Up @@ -1247,7 +1248,7 @@ impl bifrost_cross_in_out::Config for Runtime {

parameter_types! {
pub const QueryTimeout: BlockNumber = 100;
pub const ReferendumCheckInterval: BlockNumber = 300;
pub const ReferendumCheckInterval: BlockNumber = 1 * HOURS;
}

pub struct DerivativeAccountTokenFilter;
Expand Down Expand Up @@ -1879,6 +1880,7 @@ parameter_types! {
pub mod migrations {
#![allow(unused_imports)]
use super::*;
use crate::migration::update_referenda_referendum_info;
use migration::{
system_maker::SystemMakerClearPalletId, vsbond_auction::VSBondAuctionClearPalletId,
};
Expand All @@ -1888,6 +1890,9 @@ pub mod migrations {
// permanent migration, do not remove
pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
bifrost_system_staking::migration::SystemStakingOnRuntimeUpgrade<Runtime>,
bifrost_parachain_staking::migrations::v1::MigrateToV1<Runtime>,
bifrost_vtoken_voting::migration::v5::MigrateToV5<Runtime>,
update_referenda_referendum_info::MigrateReferendumInfoFor,
frame_support::migrations::RemovePallet<DemocracyStr, RocksDbWeight>,
frame_support::migrations::RemovePallet<CouncilStr, RocksDbWeight>,
frame_support::migrations::RemovePallet<TechnicalCommitteeStr, RocksDbWeight>,
Expand Down
45 changes: 45 additions & 0 deletions runtime/bifrost-kusama/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,3 +792,48 @@ pub mod vsbond_auction {
}
}
}

pub mod update_referenda_referendum_info {
use crate::{Runtime, Weight};
use frame_support::traits::OnRuntimeUpgrade;
use pallet_referenda::{ReferendumIndex, ReferendumInfoFor, ReferendumInfoOf};

pub struct MigrateReferendumInfoFor;

impl OnRuntimeUpgrade for MigrateReferendumInfoFor {
fn on_runtime_upgrade() -> Weight {
let current_block_number = frame_system::Pallet::<Runtime>::block_number();
let mut weight: Weight = Weight::zero();

// Translate the storage and update accordingly
ReferendumInfoFor::<Runtime>::translate::<ReferendumInfoOf<Runtime, ()>, _>(
|_: ReferendumIndex, value: ReferendumInfoOf<Runtime, ()>| {
weight += <Runtime as frame_system::Config>::DbWeight::get().reads(1);

if let ReferendumInfoOf::<Runtime, ()>::Ongoing(mut status) = value {
// Check if there's an alarm and update the block numbers
if let Some((mut block, (mut end_schedule_block, value))) = status.alarm {
block = block
.saturating_sub(current_block_number)
.saturating_add(block);
end_schedule_block = end_schedule_block
.saturating_sub(current_block_number)
.saturating_add(end_schedule_block);

// Update the status with the new block numbers
status.alarm = Some((block, (end_schedule_block, value)));
}

// Wrap the updated status back into the ReferendumInfo enum
Some(ReferendumInfoOf::<Runtime, ()>::Ongoing(status))
} else {
// If the status isn't Ongoing, return it unchanged
Some(value)
}
},
);

weight + <Runtime as frame_system::Config>::DbWeight::get().writes(1)
}
}
}
Loading

0 comments on commit 754e2b0

Please sign in to comment.