File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ title: 'pallet-migrations: fix index access for singluar migrations'
2+ doc:
3+ - audience: Runtime Dev
4+ description: |-
5+ Discovered a bug in the migrations pallet while debugging https://github.com/paritytech/try-runtime-cli/pull/90.
6+ It only occurs when a single MBM is configured - hence it did not happen when Ajuna Network tried it...
7+
8+ Changes:
9+ - Check len of the tuple before accessing its nth_id
10+ - Make nth_id return `None` on unary tuples and n>0
11+ crates:
12+ - name: pallet-migrations
13+ bump: patch
14+ - name: frame-support
15+ bump: patch
Original file line number Diff line number Diff line change @@ -678,7 +678,7 @@ impl<T: Config> Pallet<T> {
678678 return Some ( ControlFlow :: Break ( cursor) )
679679 }
680680
681- let Some ( id ) = T :: Migrations :: nth_id ( cursor . index ) else {
681+ if cursor . index > = T :: Migrations :: len ( ) {
682682 // No more migrations in the tuple - we are done.
683683 defensive_assert ! ( cursor. index == T :: Migrations :: len( ) , "Inconsistent MBMs tuple" ) ;
684684 Self :: deposit_event ( Event :: UpgradeCompleted ) ;
@@ -687,8 +687,9 @@ impl<T: Config> Pallet<T> {
687687 return None ;
688688 } ;
689689
690- let Ok ( bounded_id) : Result < IdentifierOf < T > , _ > = id. try_into ( ) else {
691- defensive ! ( "integrity_test ensures that all identifiers' MEL bounds fit into CursorMaxLen; qed." ) ;
690+ let id = T :: Migrations :: nth_id ( cursor. index ) . map ( TryInto :: try_into) ;
691+ let Some ( Ok ( bounded_id) ) : Option < Result < IdentifierOf < T > , _ > > = id else {
692+ defensive ! ( "integrity_test ensures that all identifiers are present and bounde; qed." ) ;
692693 Self :: upgrade_failed ( Some ( cursor. index ) ) ;
693694 return None
694695 } ;
Original file line number Diff line number Diff line change @@ -27,6 +27,31 @@ use frame_support::{pallet_prelude::Weight, traits::OnRuntimeUpgrade};
2727#[ docify:: export]
2828#[ test]
2929fn simple_works ( ) {
30+ use Event :: * ;
31+ test_closure ( || {
32+ // Add three migrations, each taking one block longer than the previous.
33+ MockedMigrations :: set ( vec ! [ ( SucceedAfter , 2 ) ] ) ;
34+
35+ System :: set_block_number ( 1 ) ;
36+ Migrations :: on_runtime_upgrade ( ) ;
37+ run_to_block ( 10 ) ;
38+
39+ // Check that the executed migrations are recorded in `Historical`.
40+ assert_eq ! ( historic( ) , vec![ mocked_id( SucceedAfter , 2 ) , ] ) ;
41+
42+ // Check that we got all events.
43+ assert_events ( vec ! [
44+ UpgradeStarted { migrations: 1 } ,
45+ MigrationAdvanced { index: 0 , took: 1 } ,
46+ MigrationAdvanced { index: 0 , took: 2 } ,
47+ MigrationCompleted { index: 0 , took: 3 } ,
48+ UpgradeCompleted ,
49+ ] ) ;
50+ } ) ;
51+ }
52+
53+ #[ test]
54+ fn simple_multiple_works ( ) {
3055 use Event :: * ;
3156 test_closure ( || {
3257 // Add three migrations, each taking one block longer than the previous.
Original file line number Diff line number Diff line change @@ -673,7 +673,8 @@ pub trait SteppedMigrations {
673673
674674 /// The `n`th [`SteppedMigration::id`].
675675 ///
676- /// Is guaranteed to return `Some` if `n < Self::len()`.
676+ /// Is guaranteed to return `Some` if `n < Self::len()`. Calling this with any index larger or
677+ /// equal to `Self::len()` MUST return `None`.
677678 fn nth_id ( n : u32 ) -> Option < Vec < u8 > > ;
678679
679680 /// The [`SteppedMigration::max_steps`] of the `n`th migration.
@@ -777,8 +778,10 @@ impl<T: SteppedMigration> SteppedMigrations for T {
777778 1
778779 }
779780
780- fn nth_id ( _n : u32 ) -> Option < Vec < u8 > > {
781- Some ( T :: id ( ) . encode ( ) )
781+ fn nth_id ( n : u32 ) -> Option < Vec < u8 > > {
782+ n. is_zero ( )
783+ . then_some ( T :: id ( ) . encode ( ) )
784+ . defensive_proof ( "nth_id should only be called with n==0" )
782785 }
783786
784787 fn nth_max_steps ( n : u32 ) -> Option < Option < u32 > > {
You can’t perform that action at this time.
0 commit comments