@@ -37,7 +37,7 @@ use frame_support::{
3737 weights:: Weight ,
3838} ;
3939use parity_scale_codec:: { Encode , Decode } ;
40- use crate :: { configuration, initializer:: SessionChangeNotification } ;
40+ use crate :: { configuration, initializer:: SessionChangeNotification , ParaLifecycle } ;
4141use sp_core:: RuntimeDebug ;
4242
4343#[ cfg( feature = "std" ) ]
@@ -180,8 +180,8 @@ decl_storage! {
180180 trait Store for Module <T : Config > as Paras {
181181 /// All parachains. Ordered ascending by ParaId. Parathreads are not included.
182182 Parachains get( fn parachains) : Vec <ParaId >;
183- /// All parathreads .
184- Parathreads : map hasher( twox_64_concat) ParaId => Option <( ) >;
183+ /// The current lifecycle of a all known Para IDs .
184+ ParaLifecycles : map hasher( twox_64_concat) ParaId => Option <ParaLifecycle >;
185185 /// The head-data of every registered para.
186186 Heads get( fn para_head) : map hasher( twox_64_concat) ParaId => Option <HeadData >;
187187 /// The validation code of every live para.
@@ -285,13 +285,12 @@ impl<T: Config> Module<T> {
285285 for outgoing_para in outgoing {
286286 if let Ok ( i) = parachains. binary_search ( & outgoing_para) {
287287 parachains. remove ( i) ;
288- } else {
289- <Self as Store >:: Parathreads :: remove ( & outgoing_para) ;
290288 }
291289
292290 <Self as Store >:: Heads :: remove ( & outgoing_para) ;
293291 <Self as Store >:: FutureCodeUpgrades :: remove ( & outgoing_para) ;
294292 <Self as Store >:: FutureCode :: remove ( & outgoing_para) ;
293+ ParaLifecycles :: remove ( & outgoing_para) ;
295294
296295 let removed_code = <Self as Store >:: CurrentCode :: take ( & outgoing_para) ;
297296 if let Some ( removed_code) = removed_code {
@@ -313,10 +312,11 @@ impl<T: Config> Module<T> {
313312
314313 if genesis_data. parachain {
315314 if let Err ( i) = parachains. binary_search ( & upcoming_para) {
315+ ParaLifecycles :: insert ( & upcoming_para, ParaLifecycle :: Parachain ) ;
316316 parachains. insert ( i, upcoming_para) ;
317317 }
318318 } else {
319- < Self as Store > :: Parathreads :: insert ( & upcoming_para, ( ) ) ;
319+ ParaLifecycles :: insert ( & upcoming_para, ParaLifecycle :: Parathread ) ;
320320 }
321321
322322 <Self as Store >:: Heads :: insert ( & upcoming_para, genesis_data. genesis_head ) ;
@@ -328,11 +328,15 @@ impl<T: Config> Module<T> {
328328 fn apply_upgrades ( parachains : & mut Vec < ParaId > ) {
329329 let upgrades = UpcomingUpgrades :: take ( ) ;
330330 for para in upgrades {
331- if Parathreads :: take ( & para) . is_some ( ) {
332- if let Err ( i) = parachains. binary_search ( & para) {
333- parachains. insert ( i, para) ;
331+ ParaLifecycles :: mutate ( & para, |v| {
332+ if * v == Some ( ParaLifecycle :: UpgradingToParachain ) {
333+ if let Err ( i) = parachains. binary_search ( & para) {
334+ ParaLifecycles :: insert ( & para, ParaLifecycle :: Parachain ) ;
335+ parachains. insert ( i, para) ;
336+ }
337+ * v = Some ( ParaLifecycle :: Parachain ) ;
334338 }
335- }
339+ } ) ;
336340 }
337341 }
338342
@@ -342,7 +346,7 @@ impl<T: Config> Module<T> {
342346 for para in downgrades {
343347 if let Ok ( i) = parachains. binary_search ( & para) {
344348 parachains. remove ( i) ;
345- Parathreads :: insert ( & para, ( ) ) ;
349+ ParaLifecycles :: insert ( & para, ParaLifecycle :: Parathread ) ;
346350 }
347351 }
348352 }
@@ -441,6 +445,12 @@ impl<T: Config> Module<T> {
441445 return weight;
442446 }
443447
448+ if genesis. parachain {
449+ ParaLifecycles :: insert ( & id, ParaLifecycle :: OnboardingAsParachain ) ;
450+ } else {
451+ ParaLifecycles :: insert ( & id, ParaLifecycle :: OnboardingAsParathread ) ;
452+ }
453+
444454 UpcomingParasGenesis :: insert ( & id, & genesis) ;
445455
446456 T :: DbWeight :: get ( ) . reads_writes ( 1 , 2 )
@@ -452,9 +462,10 @@ impl<T: Config> Module<T> {
452462 match v. binary_search ( & id) {
453463 Ok ( i) => {
454464 v. remove ( i) ;
455- UpcomingParasGenesis :: remove ( id) ;
465+ UpcomingParasGenesis :: remove ( & id) ;
466+ ParaLifecycles :: remove ( & id) ;
456467 // If a para was only in the pending state it should not be moved to `Outgoing`
457- return T :: DbWeight :: get ( ) . reads_writes ( 2 , 2 ) ;
468+ return T :: DbWeight :: get ( ) . reads_writes ( 2 , 3 ) ;
458469 }
459470 Err ( _) => T :: DbWeight :: get ( ) . reads_writes ( 1 , 0 ) ,
460471 }
@@ -465,7 +476,8 @@ impl<T: Config> Module<T> {
465476 Ok ( _) => T :: DbWeight :: get ( ) . reads_writes ( 1 , 0 ) ,
466477 Err ( i) => {
467478 v. insert ( i, id) ;
468- T :: DbWeight :: get ( ) . reads_writes ( 1 , 1 )
479+ ParaLifecycles :: insert ( & id, ParaLifecycle :: Outgoing ) ;
480+ T :: DbWeight :: get ( ) . reads_writes ( 1 , 2 )
469481 }
470482 }
471483 } ) ;
@@ -474,15 +486,57 @@ impl<T: Config> Module<T> {
474486 }
475487
476488 #[ allow( dead_code) ]
477- pub ( crate ) fn schedule_para_upgrade ( para : ParaId ) -> Weight {
478- UpcomingUpgrades :: append ( para) ;
479- T :: DbWeight :: get ( ) . writes ( 1 )
489+ pub ( crate ) fn schedule_para_upgrade ( id : ParaId ) -> Weight {
490+ if ParaLifecycles :: get ( & id) != Some ( ParaLifecycle :: Parathread ) {
491+ let weight = T :: DbWeight :: get ( ) . reads_writes ( 1 , 0 ) ;
492+ return weight;
493+ }
494+
495+ let dup = UpcomingUpgrades :: mutate ( |v| {
496+ match v. binary_search ( & id) {
497+ Ok ( _) => true ,
498+ Err ( i) => {
499+ v. insert ( i, id) ;
500+ false
501+ }
502+ }
503+ } ) ;
504+
505+ ParaLifecycles :: insert ( & id, ParaLifecycle :: UpgradingToParachain ) ;
506+
507+ if dup {
508+ let weight = T :: DbWeight :: get ( ) . reads_writes ( 2 , 1 ) ;
509+ return weight;
510+ }
511+
512+ T :: DbWeight :: get ( ) . reads_writes ( 2 , 2 )
480513 }
481514
482515 #[ allow( dead_code) ]
483- pub ( crate ) fn schedule_para_downgrade ( para : ParaId ) -> Weight {
484- UpcomingDowngrades :: append ( para) ;
485- T :: DbWeight :: get ( ) . writes ( 1 )
516+ pub ( crate ) fn schedule_para_downgrade ( id : ParaId ) -> Weight {
517+ if ParaLifecycles :: get ( & id) != Some ( ParaLifecycle :: Parachain ) {
518+ let weight = T :: DbWeight :: get ( ) . reads_writes ( 1 , 0 ) ;
519+ return weight;
520+ }
521+
522+ let dup = UpcomingDowngrades :: mutate ( |v| {
523+ match v. binary_search ( & id) {
524+ Ok ( _) => true ,
525+ Err ( i) => {
526+ v. insert ( i, id) ;
527+ false
528+ }
529+ }
530+ } ) ;
531+
532+ ParaLifecycles :: insert ( & id, ParaLifecycle :: DowngradingToParathread ) ;
533+
534+ if dup {
535+ let weight = T :: DbWeight :: get ( ) . reads_writes ( 2 , 1 ) ;
536+ return weight;
537+ }
538+
539+ T :: DbWeight :: get ( ) . reads_writes ( 2 , 2 )
486540 }
487541
488542 /// Schedule a future code upgrade of the given parachain, to be applied after inclusion
@@ -584,22 +638,30 @@ impl<T: Config> Module<T> {
584638
585639 /// Returns whether the given ID refers to a valid para.
586640 pub fn is_valid_para ( id : ParaId ) -> bool {
587- Self :: is_parachain ( id) || Self :: is_parathread ( id)
641+ match ParaLifecycles :: get ( & id) {
642+ Some ( ParaLifecycle :: Parachain ) |
643+ Some ( ParaLifecycle :: Parathread ) |
644+ Some ( ParaLifecycle :: UpgradingToParachain ) |
645+ Some ( ParaLifecycle :: DowngradingToParathread )
646+ => true ,
647+ _ => false ,
648+ }
588649 }
589650
590651 /// Whether a para ID corresponds to any live parathread.
591652 pub fn is_parachain ( id : ParaId ) -> bool {
592- Parachains :: get ( ) . binary_search ( & id) . is_ok ( )
653+ match ParaLifecycles :: get ( & id) {
654+ Some ( ParaLifecycle :: Parachain ) => true ,
655+ _ => false ,
656+ }
593657 }
594658
595659 /// Whether a para ID corresponds to any live parathread.
596660 pub fn is_parathread ( id : ParaId ) -> bool {
597- Parathreads :: get ( & id) . is_some ( )
598- }
599-
600- /// Wether a para ID is in in the onboarding queue.
601- pub fn is_upcoming ( id : ParaId ) -> bool {
602- UpcomingParas :: get ( ) . binary_search ( & id) . is_ok ( )
661+ match ParaLifecycles :: get ( & id) {
662+ Some ( ParaLifecycle :: Parathread ) => true ,
663+ _ => false ,
664+ }
603665 }
604666
605667 /// The block number of the last scheduled upgrade of the requested para. Includes future upgrades
@@ -1178,23 +1240,33 @@ mod tests {
11781240 ) ;
11791241
11801242 assert_eq ! ( <Paras as Store >:: UpcomingParas :: get( ) , vec![ c, b, a] ) ;
1181- assert ! ( <Paras as Store >:: Parathreads :: get( & a) . is_none( ) ) ;
11821243
1244+ // Lifecycle is tracked correctly
1245+ assert_eq ! ( ParaLifecycles :: get( & a) , Some ( ParaLifecycle :: OnboardingAsParathread ) ) ;
1246+ assert_eq ! ( ParaLifecycles :: get( & b) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
1247+ assert_eq ! ( ParaLifecycles :: get( & c) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
11831248
11841249 // run to block without session change.
11851250 run_to_block ( 2 , None ) ;
11861251
11871252 assert_eq ! ( Paras :: parachains( ) , Vec :: new( ) ) ;
11881253 assert_eq ! ( <Paras as Store >:: UpcomingParas :: get( ) , vec![ c, b, a] ) ;
1189- assert ! ( <Paras as Store >:: Parathreads :: get( & a) . is_none( ) ) ;
1254+
1255+ // Lifecycle is tracked correctly
1256+ assert_eq ! ( ParaLifecycles :: get( & a) , Some ( ParaLifecycle :: OnboardingAsParathread ) ) ;
1257+ assert_eq ! ( ParaLifecycles :: get( & b) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
1258+ assert_eq ! ( ParaLifecycles :: get( & c) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
11901259
11911260
11921261 run_to_block ( 3 , Some ( vec ! [ 3 ] ) ) ;
11931262
11941263 assert_eq ! ( Paras :: parachains( ) , vec![ c, b] ) ;
11951264 assert_eq ! ( <Paras as Store >:: UpcomingParas :: get( ) , Vec :: new( ) ) ;
11961265
1197- assert ! ( <Paras as Store >:: Parathreads :: get( & a) . is_some( ) ) ;
1266+ // Lifecycle is tracked correctly
1267+ assert_eq ! ( ParaLifecycles :: get( & a) , Some ( ParaLifecycle :: Parathread ) ) ;
1268+ assert_eq ! ( ParaLifecycles :: get( & b) , Some ( ParaLifecycle :: Parachain ) ) ;
1269+ assert_eq ! ( ParaLifecycles :: get( & c) , Some ( ParaLifecycle :: Parachain ) ) ;
11981270
11991271 assert_eq ! ( Paras :: current_code( & a) , Some ( vec![ 2 ] . into( ) ) ) ;
12001272 assert_eq ! ( Paras :: current_code( & b) , Some ( vec![ 1 ] . into( ) ) ) ;
@@ -1239,15 +1311,23 @@ mod tests {
12391311 ) ;
12401312
12411313 assert_eq ! ( <Paras as Store >:: UpcomingParas :: get( ) , vec![ c, b, a] ) ;
1242- assert ! ( <Paras as Store >:: Parathreads :: get( & a) . is_none( ) ) ;
1314+
1315+ // Lifecycle is tracked correctly
1316+ assert_eq ! ( ParaLifecycles :: get( & a) , Some ( ParaLifecycle :: OnboardingAsParathread ) ) ;
1317+ assert_eq ! ( ParaLifecycles :: get( & b) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
1318+ assert_eq ! ( ParaLifecycles :: get( & c) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
12431319
12441320
12451321 // run to block without session change.
12461322 run_to_block ( 2 , None ) ;
12471323
12481324 assert_eq ! ( Paras :: parachains( ) , Vec :: new( ) ) ;
12491325 assert_eq ! ( <Paras as Store >:: UpcomingParas :: get( ) , vec![ c, b, a] ) ;
1250- assert ! ( <Paras as Store >:: Parathreads :: get( & a) . is_none( ) ) ;
1326+
1327+ // Lifecycle is tracked correctly
1328+ assert_eq ! ( ParaLifecycles :: get( & a) , Some ( ParaLifecycle :: OnboardingAsParathread ) ) ;
1329+ assert_eq ! ( ParaLifecycles :: get( & b) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
1330+ assert_eq ! ( ParaLifecycles :: get( & c) , Some ( ParaLifecycle :: OnboardingAsParachain ) ) ;
12511331
12521332 Paras :: schedule_para_cleanup ( c) ;
12531333
@@ -1258,7 +1338,10 @@ mod tests {
12581338 assert_eq ! ( <Paras as Store >:: UpcomingParas :: get( ) , Vec :: new( ) ) ;
12591339 assert ! ( <Paras as Store >:: UpcomingParasGenesis :: get( a) . is_none( ) ) ;
12601340
1261- assert ! ( <Paras as Store >:: Parathreads :: get( & a) . is_some( ) ) ;
1341+ // Lifecycle is tracked correctly
1342+ assert_eq ! ( ParaLifecycles :: get( & a) , Some ( ParaLifecycle :: Parathread ) ) ;
1343+ assert_eq ! ( ParaLifecycles :: get( & b) , Some ( ParaLifecycle :: Parachain ) ) ;
1344+ assert_eq ! ( ParaLifecycles :: get( & c) , None ) ;
12621345
12631346 assert_eq ! ( Paras :: current_code( & a) , Some ( vec![ 2 ] . into( ) ) ) ;
12641347 assert_eq ! ( Paras :: current_code( & b) , Some ( vec![ 1 ] . into( ) ) ) ;
0 commit comments