Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
b878662
Frame Add translate_next
pgherveou Apr 28, 2023
7ab5774
Move to lazy migration
athei Feb 22, 2023
e49f0ce
Updates
pgherveou May 2, 2023
758902a
simplify MockMigration
pgherveou May 2, 2023
3a9c925
wip
pgherveou May 2, 2023
c7aa478
wip
pgherveou May 2, 2023
c5d33ce
add bench
pgherveou May 2, 2023
a27b8bc
add bench
pgherveou May 2, 2023
d4eee87
fmt
pgherveou May 2, 2023
f5d9638
fix bench
pgherveou May 2, 2023
dc501ce
add .
pgherveou May 2, 2023
e6cd691
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts
May 2, 2023
5db9beb
Apply suggestions from code review
pgherveou May 5, 2023
1bd551e
Scalfold v10 / v11 fix tests
pgherveou May 8, 2023
d718995
PR comment
pgherveou May 8, 2023
131cc45
tweak pub use
pgherveou May 8, 2023
1f22230
wip
pgherveou May 8, 2023
f3f69c8
wip
pgherveou May 9, 2023
1b07693
wip
pgherveou May 9, 2023
d8500b7
Merge branch 'master' into at/migration
pgherveou May 9, 2023
e561a69
misc merge master
pgherveou May 9, 2023
2a57bff
Merge branch 'at/migration' into pg/migration
pgherveou May 9, 2023
4e7a1f7
misc merge master
pgherveou May 9, 2023
b1dd6a1
Merge branch 'at/migration' into pg/migration
pgherveou May 9, 2023
db7b4e9
wip
pgherveou May 9, 2023
3c08a37
rm tmp stuff
pgherveou May 9, 2023
e966c87
wip
pgherveou May 9, 2023
f1134c6
wip
pgherveou May 10, 2023
a85ff26
wip
pgherveou May 10, 2023
87a8f3b
wip
pgherveou May 10, 2023
193c788
wip
pgherveou May 10, 2023
aafaa03
fixes
pgherveou May 10, 2023
0d84f28
add state
pgherveou May 10, 2023
be9bc81
wip
pgherveou May 10, 2023
59bd209
wip
pgherveou May 10, 2023
92ddfa0
wip
pgherveou May 10, 2023
1221345
wip
pgherveou May 10, 2023
8445ae7
wip
pgherveou May 10, 2023
42e5b5b
wip
pgherveou May 11, 2023
82ed2d1
wip
pgherveou May 11, 2023
dee4889
wip
pgherveou May 11, 2023
6aff1bd
wip
pgherveou May 11, 2023
4a7ec2e
wip
pgherveou May 11, 2023
f21b524
wip
pgherveou May 11, 2023
42cf92c
wip
pgherveou May 11, 2023
68ff246
wip
pgherveou May 11, 2023
bcd404b
wip
pgherveou May 11, 2023
0a321db
fix
pgherveou May 11, 2023
4b771b2
fixed compilation
pgherveou May 11, 2023
7864d6c
clean up logs
pgherveou May 11, 2023
2af1523
wip
pgherveou May 11, 2023
4c4758b
Revert "Frame Add translate_next"
pgherveou May 11, 2023
7f9b013
Merge branch 'master' into pg/migration
pgherveou May 11, 2023
1194ad3
Fix v10 logic
pgherveou May 12, 2023
657ac6e
Apply suggestions from code review
pgherveou May 12, 2023
69734ae
wip
pgherveou May 12, 2023
98f5df5
fixes
pgherveou May 12, 2023
14b7102
exercise del_queue
pgherveou May 12, 2023
59acab8
bump sample size
pgherveou May 12, 2023
4a142bc
fmt
pgherveou May 12, 2023
48cf78a
wip
pgherveou May 12, 2023
14f078c
blank line
pgherveou May 12, 2023
79b36b9
fix lint
pgherveou May 12, 2023
d954437
fix rustdoc job lint
pgherveou May 15, 2023
9782bd9
PR comment do not use dangerous into()
pgherveou May 15, 2023
82adfd8
Ad macros for updating mod visibility
pgherveou May 15, 2023
25b2ec6
Add doc
pgherveou May 15, 2023
453489f
Add max_weight to integrity_test
pgherveou May 15, 2023
1ceb5e0
fix compilation
pgherveou May 15, 2023
883f54f
Merge branch 'master' into pg/migration
pgherveou May 16, 2023
ab44573
Add no migration tests
pgherveou May 16, 2023
c87e1d7
Merge branch 'master' of https://github.com/paritytech/substrate into…
May 16, 2023
b8ee019
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts
May 16, 2023
2081eae
fix clippy
pgherveou May 16, 2023
aaac768
PR review
pgherveou May 16, 2023
c2e587d
Update frame/contracts/src/lib.rs
pgherveou May 16, 2023
0b690e9
Merge branch 'master' into pg/migration
pgherveou May 26, 2023
1fc4035
Fix master merge
pgherveou May 26, 2023
c6ea2eb
Merge branch 'master' into pg/migration
pgherveou May 26, 2023
0b9c16c
fix merge 2
pgherveou May 26, 2023
25ada0f
fix tryruntime
pgherveou May 28, 2023
7d5e934
fix lint
pgherveou May 29, 2023
de10f33
Merge branch 'master' into pg/migration
pgherveou May 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wip
  • Loading branch information
pgherveou committed May 12, 2023
commit 69734aec45d2c7d2a01f225e717f31e3174c12db
35 changes: 8 additions & 27 deletions frame/contracts/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use self::{
};
use crate::{
exec::{AccountIdOf, Key},
migration::{Migrate, v9, v10, v11},
migration::{v10, v11, v9, Migrate},
wasm::CallFlags,
Pallet as Contracts, *,
};
Expand Down Expand Up @@ -265,42 +265,24 @@ benchmarks! {
m.step();
}

// This benchmarks the weight of dispatching a migrate call that does nothing
#[pov_mode = Measured]
migrate_noop {
let origin: RawOrigin<<T as frame_system::Config>::AccountId> = RawOrigin::Signed(whitelisted_caller());
}: {
<Contracts<T>>::migrate(origin.into(), Weight::zero()).is_err()
}

// This benchmarks the weight of bumping the storage version.
#[pov_mode = Measured]
bump_storage_version {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 2);
let new_version = StorageVersion::new(3);
}: {
new_version.put::<Pallet<T>>();
} verify {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 3);
}

// This benchmarks the weight of executing Migration::migrate when there are no migration in progress.
// This benchmarks the weight of executing Migration::migrate to execute a noop migration.
#[pov_mode = Measured]
migration_noop {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 2);
}: {
Migration::<T>::migrate(Weight::MAX);
Migration::<T>::migrate(Weight::MAX)
} verify {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 2);
}

// This benchmarks the weight of executing Migration::migrate to execute a migration that bump the storage version.
// This benchmarks the weight of executing Migration::migrate when there are no migration in progress.
#[pov_mode = Measured]
migration {
migrate {
StorageVersion::new(0).put::<Pallet<T>>();
<Migration::<T> as frame_support::traits::OnRuntimeUpgrade>::on_runtime_upgrade();
}: {
Migration::<T>::migrate(Weight::MAX);
let origin: RawOrigin<<T as frame_system::Config>::AccountId> = RawOrigin::Signed(whitelisted_caller());
}: {
<Contracts<T>>::migrate(origin.into(), Weight::MAX).unwrap()
} verify {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 1);
}
Expand All @@ -321,7 +303,6 @@ benchmarks! {
StorageVersion::new(0).put::<Pallet<T>>();
let v = vec![42u8].try_into().ok();
MigrationInProgress::<T>::set(v.clone());

}: {
<Migration::<T> as frame_support::traits::OnRuntimeUpgrade>::on_runtime_upgrade()
} verify {
Expand Down
25 changes: 13 additions & 12 deletions frame/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,12 @@ pub mod pallet {
fn on_idle(_block: T::BlockNumber, remaining_weight: Weight) -> Weight {
use migration::MigrateResult::*;

let remaining_weight = match Migration::<T>::migrate(remaining_weight) {
(InProgress, weight) => return remaining_weight.saturating_sub(weight),
(NoMigrationPerformed | Completed, weight) =>
remaining_weight.saturating_sub(weight),
};
let (result, weight) = Migration::<T>::migrate(remaining_weight);
let remaining_weight = remaining_weight.saturating_sub(weight);

if !matches!(result, Completed | NoMigrationInProgress) {
return weight
}

ContractInfo::<T>::process_deletion_queue_batch(remaining_weight)
.saturating_add(T::WeightInfo::on_process_deletion_queue_batch())
Expand Down Expand Up @@ -735,21 +736,21 @@ pub mod pallet {
}

#[pallet::call_index(9)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note from talk with Sasha: should we give a different DispatchClass to this call?

#[pallet::weight(T::WeightInfo::migrate_noop().saturating_add(T::WeightInfo::migration()).saturating_add(*weight_limit))]
#[pallet::weight(T::WeightInfo::migrate().saturating_add(*weight_limit))]
pub fn migrate(origin: OriginFor<T>, weight_limit: Weight) -> DispatchResultWithPostInfo {
use migration::MigrateResult::*;
ensure_signed(origin)?;

let weight_limit = weight_limit.saturating_add(T::WeightInfo::migration());
let weight_limit = weight_limit.saturating_add(T::WeightInfo::migrate());
let (result, weight) = Migration::<T>::migrate(weight_limit);
let weight = weight.saturating_add(T::WeightInfo::migrate_noop());

match result {
InProgress | Completed =>
Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::No }),
NoMigrationPerformed => {
Completed => Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::No }),
InProgress { steps_done, .. } if steps_done > 0 => Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::No }),
InProgress { .. } => Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::Yes }),
NoMigrationInProgress | NoMigrationPerformed => {
let err: DispatchError = <Error<T>>::NoMigrationPerformed.into();
Err(err.with_weight(weight))
Err(err.with_weight(T::WeightInfo::migrate()))
},
}
}
Expand Down
113 changes: 54 additions & 59 deletions frame/contracts/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ pub trait MigrateSequence: private::Sealed {
}

/// Execute the migration step until the weight limit is reached.
///
/// Returns the new cursor or `None` if the migration is finished.
fn steps(version: StorageVersion, cursor: &[u8], weight_left: &mut Weight) -> Option<Cursor>;
fn steps(version: StorageVersion, cursor: &[u8], weight_left: &mut Weight) -> StepResult;

/// Verify that each migration's cursor fits into `Cursor`.
fn integrity_test();
Expand Down Expand Up @@ -252,17 +250,26 @@ impl<T: Config, M: MigrateSequence> OnRuntimeUpgrade for Migration<T, M> {
}
}

/// The result of a migration step.
/// The result of running the migration.
#[derive(Debug, PartialEq)]
pub enum MigrateResult {
/// No migration was performed
NoMigrationPerformed,
/// No migration currently in progress
NoMigrationInProgress,
/// A migration is in progress
InProgress,
InProgress { steps_done: u32 },
/// All migrations are completed
Completed,
}

/// The result of running a migration step.
#[derive(Debug, PartialEq)]
pub enum StepResult {
InProgress { cursor: Cursor, steps_done: u32 },
Completed { steps_done: u32 },
}

impl<T: Config, M: MigrateSequence> Migration<T, M> {
/// Verify that each migration's step of the MigrateSequence fits into `Cursor`.
pub(crate) fn integrity_test() {
Expand All @@ -275,13 +282,13 @@ impl<T: Config, M: MigrateSequence> Migration<T, M> {
let name = <Pallet<T>>::name();
let mut weight_left = weight_limit;

if weight_left.checked_reduce(T::WeightInfo::migration()).is_none() {
if weight_left.checked_reduce(T::WeightInfo::migrate()).is_none() {
return (MigrateResult::NoMigrationPerformed, Weight::zero())
}

MigrationInProgress::<T>::mutate_exists(|progress| {
let Some(cursor_before) = progress.as_mut() else {
return (MigrateResult::NoMigrationPerformed, T::WeightInfo::migration_noop())
return (MigrateResult::NoMigrationInProgress, T::WeightInfo::migration_noop())
};

// if a migration is running it is always upgrading to the next version
Expand All @@ -295,45 +302,30 @@ impl<T: Config, M: MigrateSequence> Migration<T, M> {
in_progress_version,
);

*progress =
match M::steps(in_progress_version, cursor_before.as_ref(), &mut weight_left) {
// ongoing
Some(cursor) => {
// refund as we did not update the storage version
weight_left.saturating_accrue(T::WeightInfo::bump_storage_version());
// we still have a cursor which keeps the pallet disabled
Some(cursor)
},
// finished
None => {
in_progress_version.put::<Pallet<T>>();
if <Pallet<T>>::current_storage_version() != in_progress_version {
// chain the next migration
log::info!(
target: LOG_TARGET,
"{name}: Next migration is {:?},",
in_progress_version + 1,
);

Some(M::new(in_progress_version + 1))
} else {
// enable pallet by removing the storage item
log::info!(
target: LOG_TARGET,
"{name}: All migrations done. At version {:?},",
in_progress_version,
);
None
}
},
};

let state = match progress {
Some(_) => MigrateResult::InProgress,
None => MigrateResult::Completed,
let result = match M::steps(
in_progress_version,
cursor_before.as_ref(),
&mut weight_left,
) {
StepResult::InProgress { cursor, steps_done } => {
*progress = Some(cursor);
MigrateResult::InProgress { steps_done }
},
StepResult::Completed { steps_done } => {
in_progress_version.put::<Pallet<T>>();
if <Pallet<T>>::current_storage_version() != in_progress_version {
log::info!( target: LOG_TARGET, "{name}: Next migration is {:?},", in_progress_version + 1);
*progress = Some(M::new(in_progress_version + 1));
MigrateResult::InProgress { steps_done }
} else {
log::info!( target: LOG_TARGET, "{name}: All migrations done. At version {:?},", in_progress_version);
*progress = None;
MigrateResult::Completed
}
},
};

(state, weight_limit.saturating_sub(weight_left))
(result, weight_limit.saturating_sub(weight_left))
})
}

Expand Down Expand Up @@ -408,25 +400,23 @@ impl MigrateSequence for Tuple {
invalid_version(version)
}

fn steps(
version: StorageVersion,
mut cursor: &[u8],
weight_left: &mut Weight,
) -> Option<Cursor> {
fn steps(version: StorageVersion, mut cursor: &[u8], weight_left: &mut Weight) -> StepResult {
for_tuples!(
#(
if version == Tuple::VERSION {
let mut migration = <Tuple as Decode>::decode(&mut cursor)
.expect(PROOF_DECODE);
let max_weight = Tuple::max_step_weight();
let mut steps_done = 0;
while weight_left.all_gt(max_weight) {
let (finished, weight) = migration.step();
steps_done += 1;
weight_left.saturating_reduce(weight);
if matches!(finished, IsFinished::Yes) {
return None
return StepResult::Completed{ steps_done }
}
}
return Some(migration.encode().try_into().expect(PROOF_ENCODE))
return StepResult::InProgress{cursor: migration.encode().try_into().expect(PROOF_ENCODE), steps_done }
}
)*
);
Expand Down Expand Up @@ -510,25 +500,29 @@ mod test {
fn steps_works() {
type M = (MockMigration<2>, MockMigration<3>);
let version = StorageVersion::new(2);
let cursor = M::new(version);
let mut cursor = M::new(version);

let mut weight = Weight::from_all(2);
let cursor = M::steps(version, &cursor, &mut weight).unwrap();
assert_eq!(cursor.to_vec(), vec![1u8, 0]);
let result = M::steps(version, &cursor, &mut weight);
cursor = vec![1u8, 0].try_into().unwrap();
assert_eq!(result, StepResult::InProgress { cursor: cursor.clone(), steps_done: 1 });
assert_eq!(weight, Weight::from_all(1));

let mut weight = Weight::from_all(2);
assert!(M::steps(version, &cursor, &mut weight).is_none());
assert_eq!(
M::steps(version, &cursor, &mut weight),
StepResult::Completed { steps_done: 1 }
);
}

#[test]
fn no_migration_performed_works() {
fn no_migration_in_progress_works() {
type M = (MockMigration<1>, MockMigration<2>);
type TestMigration = Migration<Test, M>;

ExtBuilder::default().build().execute_with(|| {
assert_eq!(StorageVersion::get::<Pallet<Test>>(), 2);
assert_eq!(TestMigration::migrate(Weight::MAX).0, MigrateResult::NoMigrationPerformed)
assert_eq!(TestMigration::migrate(Weight::MAX).0, MigrateResult::NoMigrationInProgress)
});
}

Expand All @@ -540,7 +534,8 @@ mod test {
ExtBuilder::default().set_storage_version(0).build().execute_with(|| {
assert_eq!(StorageVersion::get::<Pallet<Test>>(), 0);
TestMigration::on_runtime_upgrade();
for (version, status) in [(1, MigrateResult::InProgress), (2, MigrateResult::Completed)]
for (version, status) in
[(1, MigrateResult::InProgress { steps_done: 1 }), (2, MigrateResult::Completed)]
{
assert_eq!(TestMigration::migrate(Weight::MAX).0, status);
assert_eq!(
Expand All @@ -549,7 +544,7 @@ mod test {
);
}

assert_eq!(TestMigration::migrate(Weight::MAX).0, MigrateResult::NoMigrationPerformed);
assert_eq!(TestMigration::migrate(Weight::MAX).0, MigrateResult::NoMigrationInProgress);
assert_eq!(StorageVersion::get::<Pallet<Test>>(), 2);
});
}
Expand Down
Loading