Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asynchronous block generation adaption #1628

Merged
merged 11 commits into from
Feb 6, 2025
Merged
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