Skip to content

Commit 8465175

Browse files
authored
Add Priority Config to the xcm metrics (#32)
* Add Priority Config to the xcm metrics * update event
1 parent 9c26320 commit 8465175

File tree

6 files changed

+237
-28
lines changed

6 files changed

+237
-28
lines changed

backend/src/routes/updates.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ type EventType =
2626
| 'dmpMessageCounter'
2727
| 'umpMessageCounter'
2828
| 'dmpQueueEvent'
29-
| 'umpQueueEvent';
29+
| 'umpQueueEvent'
30+
| 'dmpQueuePriority'
31+
| 'umpQueuePriority';
3032

3133
export const updatesHandler: RequestHandler = async (req: Request, res: Response) => {
3234
const requestedEvents = ((req.query.events as string) || '')

backend/src/services/BlockProcessor.ts

Lines changed: 156 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { PalletRcMigratorMigrationStage } from '../types/pjs';
1+
import type { PalletRcMigratorMigrationStage, PalletRcMigratorQueuePriority } from '../types/pjs';
22
import type { ApiDecoration } from '@polkadot/api/types';
33
import type { Vec, Bytes } from '@polkadot/types';
44
import type { Event } from '@polkadot/types/interfaces';
@@ -51,6 +51,8 @@ export class BlockProcessor {
5151
private previousDmpQueueSize: number = 0;
5252
private currentMode: ProcessingMode = ProcessingMode.DETECTION;
5353
private migrationStartBlockNumber?: number;
54+
private rcPriorityConfigQueried: boolean = false;
55+
private ahPriorityConfigQueried: boolean = false;
5456

5557
private constructor() {
5658
// Initialize queues for both chains
@@ -62,6 +64,8 @@ export class BlockProcessor {
6264
this.lastBlockNumber.set('relay-chain', 0);
6365
this.lastBlockNumber.set('asset-hub', 0);
6466
this.currentMode = ProcessingMode.DETECTION;
67+
this.rcPriorityConfigQueried = false;
68+
this.ahPriorityConfigQueried = false;
6569
}
6670

6771
/**
@@ -429,6 +433,11 @@ export class BlockProcessor {
429433
if (event.section === 'parachainSystem' && event.method === 'UpwardMessageSent') {
430434
await this.handleAssetHubUpwardMessageSent(event, item);
431435
}
436+
437+
// Handle ahMigrator.DmpQueuePrioritySet event
438+
if (event.section === 'ahMigrator' && event.method === 'DmpQueuePriorityConfigSet') {
439+
await this.handleDmpQueuePriorityChangedEvent(event, apiAt, item);
440+
}
432441
}
433442

434443
// Emit pallet migration events after processing all events in this block
@@ -473,6 +482,11 @@ export class BlockProcessor {
473482
if (event.section === 'messageQueue' && event.method === 'Processed') {
474483
await this.handleRelayChainMessageQueueProcessed(event, item);
475484
}
485+
486+
// Handle rcMigrator.AhUmpQueuePriorityConfigSet event
487+
if (event.section === 'rcMigrator' && event.method === 'AhUmpQueuePriorityConfigSet') {
488+
await this.handleUmpQueuePriorityChangedEvent(event, apiAt, item);
489+
}
476490
}
477491
} catch (error) {
478492
Log.service({
@@ -640,7 +654,7 @@ export class BlockProcessor {
640654
* Relay Chain event handlers
641655
*/
642656
private async handleRelayChainMessageQueueProcessed(
643-
event: Event,
657+
_: Event,
644658
item: QueueItem
645659
): Promise<void> {
646660
try {
@@ -686,11 +700,23 @@ export class BlockProcessor {
686700
item: QueueItem
687701
): Promise<void> {
688702
try {
689-
const [pendingUpwardMessages] = await Promise.all([
690-
apiAt.query.parachainSystem.pendingUpwardMessages<Vec<Bytes>>(),
691-
]);
703+
// Query priority config only once on first full mode block
704+
if (!this.ahPriorityConfigQueried) {
705+
const [pendingUpwardMessages, dmpQueuePriority] = await Promise.all([
706+
apiAt.query.parachainSystem.pendingUpwardMessages<Vec<Bytes>>(),
707+
apiAt.query.ahMigrator.dmpQueuePriorityConfig<PalletRcMigratorQueuePriority>(),
708+
]);
709+
710+
await this.handleAhPendingUpwardMessages(pendingUpwardMessages, item);
711+
await this.handleDmpQueuePriority(dmpQueuePriority, item);
712+
this.ahPriorityConfigQueried = true;
713+
} else {
714+
const [pendingUpwardMessages] = await Promise.all([
715+
apiAt.query.parachainSystem.pendingUpwardMessages<Vec<Bytes>>(),
716+
]);
692717

693-
await this.handleAhPendingUpwardMessages(pendingUpwardMessages, item);
718+
await this.handleAhPendingUpwardMessages(pendingUpwardMessages, item);
719+
}
694720
// TODO: Query Asset Hub specific storage:
695721
// - ahMigrator.ahMigrationStage (Do we actually need this?)
696722

@@ -717,16 +743,32 @@ export class BlockProcessor {
717743
item: QueueItem
718744
): Promise<void> {
719745
try {
720-
const [migrationStage, dmpMessageQueue] = await Promise.all([
721-
apiAt.query.rcMigrator.rcMigrationStage<PalletRcMigratorMigrationStage>(),
722-
apiAt.query.dmp.downwardMessageQueues<Vec<PolkadotCorePrimitivesInboundDownwardMessage>>(
723-
1000
724-
),
725-
]);
726-
727-
// TODO: Is there specific ordering to this or can we put it in a Promise.all?
728-
await this.handleRcMigrationStage(migrationStage, item);
729-
await this.handleRcDownwardMessageQueues(dmpMessageQueue, item);
746+
// Query priority config only once on first full mode block
747+
if (!this.rcPriorityConfigQueried) {
748+
const [migrationStage, dmpMessageQueue, umpQueuePriority] = await Promise.all([
749+
apiAt.query.rcMigrator.rcMigrationStage<PalletRcMigratorMigrationStage>(),
750+
apiAt.query.dmp.downwardMessageQueues<Vec<PolkadotCorePrimitivesInboundDownwardMessage>>(
751+
1000
752+
),
753+
apiAt.query.rcMigrator.ahUmpQueuePriorityConfig<PalletRcMigratorQueuePriority>(),
754+
]);
755+
756+
await this.handleRcMigrationStage(migrationStage, item);
757+
await this.handleRcDownwardMessageQueues(dmpMessageQueue, item);
758+
await this.handleUmpQueuePriority(umpQueuePriority, item);
759+
760+
this.rcPriorityConfigQueried = true;
761+
} else {
762+
const [migrationStage, dmpMessageQueue] = await Promise.all([
763+
apiAt.query.rcMigrator.rcMigrationStage<PalletRcMigratorMigrationStage>(),
764+
apiAt.query.dmp.downwardMessageQueues<Vec<PolkadotCorePrimitivesInboundDownwardMessage>>(
765+
1000
766+
),
767+
]);
768+
769+
await this.handleRcMigrationStage(migrationStage, item);
770+
await this.handleRcDownwardMessageQueues(dmpMessageQueue, item);
771+
}
730772

731773
Log.service({
732774
service: 'Block Processor',
@@ -927,6 +969,104 @@ export class BlockProcessor {
927969
}
928970
}
929971

972+
private async handleUmpQueuePriority(
973+
queuePriority: PalletRcMigratorQueuePriority,
974+
item: QueueItem
975+
): Promise<void> {
976+
try {
977+
const priorityType = queuePriority.type;
978+
979+
eventService.emit('umpQueuePriority', {
980+
type: priorityType,
981+
timestamp: new Date(item.timestamp!).toISOString(),
982+
});
983+
984+
Log.service({
985+
service: 'UMP Queue Priority',
986+
action: 'UMP queue priority config retrieved',
987+
details: { type: priorityType },
988+
});
989+
} catch (error) {
990+
Log.service({
991+
service: 'UMP Queue Priority',
992+
action: 'Error processing UMP queue priority',
993+
error: error as Error,
994+
});
995+
}
996+
}
997+
998+
private async handleDmpQueuePriority(
999+
queuePriority: any,
1000+
item: QueueItem
1001+
): Promise<void> {
1002+
try {
1003+
const priorityType = queuePriority.type;
1004+
1005+
eventService.emit('dmpQueuePriority', {
1006+
type: priorityType,
1007+
timestamp: new Date(item.timestamp!).toISOString(),
1008+
});
1009+
1010+
Log.service({
1011+
service: 'DMP Queue Priority',
1012+
action: 'DMP queue priority config retrieved',
1013+
details: { type: priorityType },
1014+
});
1015+
} catch (error) {
1016+
Log.service({
1017+
service: 'DMP Queue Priority',
1018+
action: 'Error processing DMP queue priority',
1019+
error: error as Error,
1020+
});
1021+
}
1022+
}
1023+
1024+
private async handleUmpQueuePriorityChangedEvent(
1025+
_: Event,
1026+
apiAt: ApiDecoration<'promise'>,
1027+
item: QueueItem
1028+
): Promise<void> {
1029+
try {
1030+
Log.service({
1031+
service: 'UMP Queue Priority',
1032+
action: 'AhUmpQueuePrioritySet event detected - re-querying config',
1033+
details: { blockNumber: item.blockNumber },
1034+
});
1035+
1036+
const umpQueuePriority = await apiAt.query.rcMigrator.ahUmpQueuePriorityConfig<PalletRcMigratorQueuePriority>();
1037+
await this.handleUmpQueuePriority(umpQueuePriority, item);
1038+
} catch (error) {
1039+
Log.service({
1040+
service: 'UMP Queue Priority',
1041+
action: 'Error handling UMP priority change event',
1042+
error: error as Error,
1043+
});
1044+
}
1045+
}
1046+
1047+
private async handleDmpQueuePriorityChangedEvent(
1048+
_: Event,
1049+
apiAt: ApiDecoration<'promise'>,
1050+
item: QueueItem
1051+
): Promise<void> {
1052+
try {
1053+
Log.service({
1054+
service: 'DMP Queue Priority',
1055+
action: 'DmpQueuePrioritySet event detected - re-querying config',
1056+
details: { blockNumber: item.blockNumber },
1057+
});
1058+
1059+
const dmpQueuePriority = await apiAt.query.ahMigrator.dmpQueuePriorityConfig();
1060+
await this.handleDmpQueuePriority(dmpQueuePriority, item);
1061+
} catch (error) {
1062+
Log.service({
1063+
service: 'DMP Queue Priority',
1064+
action: 'Error handling DMP priority change event',
1065+
error: error as Error,
1066+
});
1067+
}
1068+
}
1069+
9301070
/**
9311071
* Lightweight detection mode - only looks for migration scheduling events on Relay Chain
9321072
*/

backend/src/types/pjs.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ interface PalletRcMigratorCall extends Enum {
2929
| 'UpdateAhMsgProcessedCount';
3030
}
3131

32+
/** @name PalletRcMigratorQueuePriority (552) */
33+
export interface PalletRcMigratorQueuePriority extends Enum {
34+
readonly isConfig: boolean;
35+
readonly isOverrideConfig: boolean;
36+
readonly asOverrideConfig: ITuple<[u32, u32]>;
37+
readonly isDisabled: boolean;
38+
readonly type: 'Config' | 'OverrideConfig' | 'Disabled';
39+
}
40+
3241
/** @name PalletRcMigratorMigrationStage (503) */
3342
export interface PalletRcMigratorMigrationStage extends Enum {
3443
readonly isPending: boolean;

frontend/src/components/XcmMessageMetrics.css

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,28 @@
9595
font-weight: 600;
9696
}
9797

98-
.priority-enabled {
99-
background: #d4edda;
100-
color: #155724;
101-
border: 1px solid #c3e6cb;
98+
.priority-default {
99+
background: rgba(52, 211, 153, 0.15);
100+
color: #10b981;
101+
border: 1px solid rgba(52, 211, 153, 0.3);
102+
}
103+
104+
.priority-override {
105+
background: rgba(251, 191, 36, 0.15);
106+
color: #f59e0b;
107+
border: 1px solid rgba(251, 191, 36, 0.3);
102108
}
103109

104110
.priority-disabled {
105-
background: #f8d7da;
106-
color: #721c24;
107-
border: 1px solid #f5c6cb;
111+
background: rgba(239, 68, 68, 0.15);
112+
color: #ef4444;
113+
border: 1px solid rgba(239, 68, 68, 0.3);
114+
}
115+
116+
.priority-unknown {
117+
background: rgba(156, 163, 175, 0.15);
118+
color: #9ca3af;
119+
border: 1px solid rgba(156, 163, 175, 0.3);
108120
}
109121

110122
.xcm-divider {

frontend/src/components/XcmMessageMetrics.tsx

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,18 @@ interface QueueEvent {
1818
timestamp: string;
1919
}
2020

21+
interface PriorityConfig {
22+
type: string;
23+
timestamp: string;
24+
}
25+
2126
const XcmMessageMetrics: React.FC = () => {
2227
const [dmpCounter, setDmpCounter] = useState<XcmCounter | null>(null);
2328
const [umpCounter, setUmpCounter] = useState<XcmCounter | null>(null);
2429
const [dmpQueueEvent, setDmpQueueEvent] = useState<QueueEvent | null>(null);
2530
const [umpQueueEvent, setUmpQueueEvent] = useState<QueueEvent | null>(null);
31+
const [dmpPriority, setDmpPriority] = useState<PriorityConfig | null>(null);
32+
const [umpPriority, setUmpPriority] = useState<PriorityConfig | null>(null);
2633

2734
// Subscribe to DMP message counter events (Relay → Asset Hub)
2835
useEventSource(['dmpMessageCounter'], useCallback((eventType: EventType, data: XcmCounter) => {
@@ -52,6 +59,20 @@ const XcmMessageMetrics: React.FC = () => {
5259
}
5360
}, []));
5461

62+
// Subscribe to DMP queue priority events
63+
useEventSource(['dmpQueuePriority'], useCallback((eventType: EventType, data: PriorityConfig) => {
64+
if (eventType === 'dmpQueuePriority') {
65+
setDmpPriority(data);
66+
}
67+
}, []));
68+
69+
// Subscribe to UMP queue priority events
70+
useEventSource(['umpQueuePriority'], useCallback((eventType: EventType, data: PriorityConfig) => {
71+
if (eventType === 'umpQueuePriority') {
72+
setUmpPriority(data);
73+
}
74+
}, []));
75+
5576
// Format bytes for display
5677
const formatBytes = (bytes: number): string => {
5778
if (bytes === 0) return '0 KB';
@@ -66,6 +87,27 @@ const XcmMessageMetrics: React.FC = () => {
6687
return `${size.toLocaleString()} messages`;
6788
};
6889

90+
// Format priority display
91+
const formatPriority = (config: PriorityConfig | null) => {
92+
if (!config) {
93+
return { text: 'Loading...', className: 'priority-unknown' };
94+
}
95+
96+
switch (config.type) {
97+
case 'Config':
98+
return { text: 'Default Config', className: 'priority-default' };
99+
case 'OverrideConfig':
100+
return { text: 'Override', className: 'priority-override' };
101+
case 'Disabled':
102+
return { text: 'Disabled', className: 'priority-disabled' };
103+
default:
104+
return { text: config.type, className: 'priority-unknown' };
105+
}
106+
};
107+
108+
const dmpPriorityDisplay = formatPriority(dmpPriority);
109+
const umpPriorityDisplay = formatPriority(umpPriority);
110+
69111
return (
70112
<section className="card xcm-metrics">
71113
<div className="card-header">
@@ -105,7 +147,9 @@ const XcmMessageMetrics: React.FC = () => {
105147
<div className="xcm-metric">
106148
<div className="xcm-metric-label">Priority</div>
107149
<div className="xcm-metric-value xcm-metric-priority">
108-
<span className="priority-badge priority-enabled">Enabled ✓</span>
150+
<span className={`priority-badge ${dmpPriorityDisplay.className}`}>
151+
{dmpPriorityDisplay.text}
152+
</span>
109153
</div>
110154
</div>
111155
</div>
@@ -145,7 +189,9 @@ const XcmMessageMetrics: React.FC = () => {
145189
<div className="xcm-metric">
146190
<div className="xcm-metric-label">Priority</div>
147191
<div className="xcm-metric-value xcm-metric-priority">
148-
<span className="priority-badge priority-enabled">Enabled ✓</span>
192+
<span className={`priority-badge ${umpPriorityDisplay.className}`}>
193+
{umpPriorityDisplay.text}
194+
</span>
149195
</div>
150196
</div>
151197
</div>

0 commit comments

Comments
 (0)