@@ -55,6 +55,7 @@ export class BlockProcessor {
5555 private migrationStartBlockNumber ?: number ;
5656 private rcPriorityConfigQueried : boolean = false ;
5757 private ahPriorityConfigQueried : boolean = false ;
58+ private initialStageCheckDone : boolean = false ;
5859
5960 private constructor ( ) {
6061 // Initialize queues for both chains
@@ -342,6 +343,11 @@ export class BlockProcessor {
342343 } ,
343344 } ) ;
344345
346+ // Initial stage check - only on Relay Chain, only once, only if no stages in DB
347+ if ( item . chain === 'relay-chain' && ! this . initialStageCheckDone ) {
348+ await this . performInitialStageCheck ( apiAt , item ) ;
349+ }
350+
345351 if ( this . currentMode === ProcessingMode . DETECTION ) {
346352 // Detection mode: only process relay chain for migration events
347353 if ( item . chain === 'relay-chain' ) {
@@ -1164,6 +1170,78 @@ export class BlockProcessor {
11641170 }
11651171 }
11661172
1173+ /**
1174+ * Perform an initial stage check on startup to see if migration is already scheduled/ongoing
1175+ * This runs only once when processing the first Relay Chain block
1176+ */
1177+ private async performInitialStageCheck (
1178+ apiAt : ApiDecoration < 'promise' > ,
1179+ item : QueueItem
1180+ ) : Promise < void > {
1181+ try {
1182+ // Check if we already have stage data in the database
1183+ const existingStage = await db . query . migrationStages . findFirst ( {
1184+ where : eq ( migrationStages . chain , 'relay-chain' ) ,
1185+ } ) ;
1186+
1187+ // If we already have stage data, skip this check
1188+ if ( existingStage ) {
1189+ Log . service ( {
1190+ service : 'Block Processor' ,
1191+ action : 'Skipping initial stage check - stages already in DB' ,
1192+ details : { existingStage : existingStage . stage } ,
1193+ } ) ;
1194+ this . initialStageCheckDone = true ;
1195+ return ;
1196+ }
1197+
1198+ // Query the current migration stage
1199+ const rcMigrationStage = await apiAt . query . rcMigrator . rcMigrationStage < PalletRcMigratorMigrationStage > ( ) ;
1200+
1201+ const stageType = rcMigrationStage . type ;
1202+ const isOngoing = ! rcMigrationStage . isPending && ! rcMigrationStage . isScheduled ;
1203+
1204+ Log . service ( {
1205+ service : 'Block Processor' ,
1206+ action : 'Initial stage check performed' ,
1207+ details : {
1208+ stageType,
1209+ isScheduled : rcMigrationStage . isScheduled ,
1210+ isOngoing,
1211+ } ,
1212+ } ) ;
1213+
1214+ // Store the stage in the database
1215+ await this . handleRcMigrationStage ( rcMigrationStage , item ) ;
1216+
1217+ // If migration is scheduled or ongoing, switch to FULL mode immediately
1218+ if ( isOngoing ) {
1219+
1220+ this . currentMode = ProcessingMode . FULL ;
1221+
1222+ Log . service ( {
1223+ service : 'Block Processor' ,
1224+ action : 'Switching to FULL mode from initial check' ,
1225+ details : {
1226+ reason : rcMigrationStage . isScheduled ? 'Migration is scheduled' : 'Migration is ongoing' ,
1227+ migrationBlockNumber : this . migrationStartBlockNumber ,
1228+ currentBlock : item . blockNumber ,
1229+ } ,
1230+ } ) ;
1231+ }
1232+
1233+ this . initialStageCheckDone = true ;
1234+ } catch ( error ) {
1235+ Log . service ( {
1236+ service : 'Block Processor' ,
1237+ action : 'Error in initial stage check' ,
1238+ error : error as Error ,
1239+ } ) ;
1240+ // Mark as done even on error to avoid retrying every block
1241+ this . initialStageCheckDone = true ;
1242+ }
1243+ }
1244+
11671245 /**
11681246 * Lightweight detection mode - only looks for migration scheduling events on Relay Chain
11691247 */
0 commit comments