frame-system: Add last_runtime_upgrade_spec_version (#2351)

Adds a function for querying the last runtime upgrade spec version. This
can be useful for when writing runtime level migrations to ensure that
they are not executed multiple times. An example would be a session key
migration.

---------

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Bastian Köcher
2023-11-15 23:54:08 +01:00
committed by GitHub
parent f4bb17cc86
commit ea4085ab74
5 changed files with 71 additions and 27 deletions
+26 -26
View File
@@ -487,6 +487,12 @@ where
let mut weight = Weight::zero();
if Self::runtime_upgraded() {
weight = weight.saturating_add(Self::execute_on_runtime_upgrade());
frame_system::LastRuntimeUpgrade::<System>::put(
frame_system::LastRuntimeUpgradeInfo::from(
<System::Version as frame_support::traits::Get<_>>::get(),
),
);
}
<frame_system::Pallet<System>>::initialize(block_number, parent_hash, digest);
weight = weight.saturating_add(<AllPalletsWithSystem as OnInitialize<
@@ -503,19 +509,12 @@ where
frame_system::Pallet::<System>::note_finished_initialize();
}
/// Returns if the runtime was upgraded since the last time this function was called.
/// Returns if the runtime has been upgraded, based on [`frame_system::LastRuntimeUpgrade`].
fn runtime_upgraded() -> bool {
let last = frame_system::LastRuntimeUpgrade::<System>::get();
let current = <System::Version as frame_support::traits::Get<_>>::get();
if last.map(|v| v.was_upgraded(&current)).unwrap_or(true) {
frame_system::LastRuntimeUpgrade::<System>::put(
frame_system::LastRuntimeUpgradeInfo::from(current),
);
true
} else {
false
}
last.map(|v| v.was_upgraded(&current)).unwrap_or(true)
}
fn initial_checks(block: &Block) {
@@ -755,7 +754,7 @@ mod tests {
traits::{fungible, ConstU32, ConstU64, ConstU8, Currency},
weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFee},
};
use frame_system::{ChainContext, LastRuntimeUpgradeInfo};
use frame_system::{ChainContext, LastRuntimeUpgrade, LastRuntimeUpgradeInfo};
use pallet_balances::Call as BalancesCall;
use pallet_transaction_payment::CurrencyAdapter;
@@ -994,6 +993,9 @@ mod tests {
sp_io::storage::set(TEST_KEY, "custom_upgrade".as_bytes());
sp_io::storage::set(CUSTOM_ON_RUNTIME_KEY, &true.encode());
System::deposit_event(frame_system::Event::CodeUpdated);
assert_eq!(0, System::last_runtime_upgrade_spec_version());
Weight::from_parts(100, 0)
}
}
@@ -1356,17 +1358,13 @@ mod tests {
new_test_ext(1).execute_with(|| {
RuntimeVersionTestValues::mutate(|v| *v = Default::default());
// It should be added at genesis
assert!(frame_system::LastRuntimeUpgrade::<Runtime>::exists());
assert!(LastRuntimeUpgrade::<Runtime>::exists());
assert!(!Executive::runtime_upgraded());
RuntimeVersionTestValues::mutate(|v| {
*v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() }
});
assert!(Executive::runtime_upgraded());
assert_eq!(
Some(LastRuntimeUpgradeInfo { spec_version: 1.into(), spec_name: "".into() }),
frame_system::LastRuntimeUpgrade::<Runtime>::get(),
);
RuntimeVersionTestValues::mutate(|v| {
*v = sp_version::RuntimeVersion {
@@ -1376,27 +1374,18 @@ mod tests {
}
});
assert!(Executive::runtime_upgraded());
assert_eq!(
Some(LastRuntimeUpgradeInfo { spec_version: 1.into(), spec_name: "test".into() }),
frame_system::LastRuntimeUpgrade::<Runtime>::get(),
);
RuntimeVersionTestValues::mutate(|v| {
*v = sp_version::RuntimeVersion {
spec_version: 1,
spec_name: "test".into(),
spec_version: 0,
impl_version: 2,
..Default::default()
}
});
assert!(!Executive::runtime_upgraded());
frame_system::LastRuntimeUpgrade::<Runtime>::take();
LastRuntimeUpgrade::<Runtime>::take();
assert!(Executive::runtime_upgraded());
assert_eq!(
Some(LastRuntimeUpgradeInfo { spec_version: 1.into(), spec_name: "test".into() }),
frame_system::LastRuntimeUpgrade::<Runtime>::get(),
);
})
}
@@ -1444,6 +1433,10 @@ mod tests {
assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module");
assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode());
assert_eq!(
Some(RuntimeVersionTestValues::get().into()),
LastRuntimeUpgrade::<Runtime>::get(),
)
});
}
@@ -1519,6 +1512,9 @@ mod tests {
#[test]
fn all_weights_are_recorded_correctly() {
// Reset to get the correct new genesis below.
RuntimeVersionTestValues::take();
new_test_ext(1).execute_with(|| {
// Make sure `on_runtime_upgrade` is called for maximum complexity
RuntimeVersionTestValues::mutate(|v| {
@@ -1535,6 +1531,10 @@ mod tests {
Digest::default(),
));
// Reset the last runtime upgrade info, to make the second call to `on_runtime_upgrade`
// succeed.
LastRuntimeUpgrade::<Runtime>::take();
// All weights that show up in the `initialize_block_impl`
let custom_runtime_upgrade_weight = CustomOnRuntimeUpgrade::on_runtime_upgrade();
let runtime_upgrade_weight =