diff --git a/src/services/coretime/CoretimeService.spec.ts b/src/services/coretime/CoretimeService.spec.ts index 26a64d39d..2d8ced3c6 100644 --- a/src/services/coretime/CoretimeService.spec.ts +++ b/src/services/coretime/CoretimeService.spec.ts @@ -15,18 +15,20 @@ // along with this program. If not, see . import { ApiPromise } from '@polkadot/api'; -// import { StorageKey } from '@polkadot/types'; import { Hash } from '@polkadot/types/interfaces'; import { kusamaCoretimeMetadata } from '../../test-helpers/metadata/coretimeKusamaMetadata'; -// import { coretimeKusamaRegistryV1003003 } from '../../test-helpers/registries/coretimeChainKusamaRegistry'; +import { kusamaMetadataV1003003 } from '../../test-helpers/metadata/kusamaMetadataV1003003'; import { createApiWithAugmentations, TypeFactory } from '../../test-helpers/typeFactory'; import { blockHash22887036 } from '../test-helpers/mock'; import { + mockCoreDescriptors, mockLeases, + mockParasLifeCycles, mockRegions, mockReservations, mockWorkloads, + mockWorkplans, potentialRenewalsMocks, } from '../test-helpers/mock/coretime'; import { blockHash26187139 } from '../test-helpers/mock/mockBlock26187139'; @@ -34,41 +36,11 @@ import { mockKusamaCoretimeApiBlock26187139 } from '../test-helpers/mock/mockCor import { mockKusamaApiBlock26187139 } from '../test-helpers/mock/mockKusamaApiBlock26187139'; import { CoretimeService } from './CoretimeService'; -const mockKusamaApi = { - ...mockKusamaApiBlock26187139, - at: (_hash: Hash) => mockKusamaApi, - consts: { - ...mockKusamaApiBlock26187139.consts, - coretime: { - brokerId: 1, - }, - onDemandAssignmentProvider: { - maxHistoricalRevenue: '50', - }, - }, - query: { - coretimeAssignmentProvider: { - coreSchedules: { - entries: () => [], - }, - coreDescriptors: { - entries: () => [], - }, - palletVersion: () => Promise.resolve().then(() => '1'), - }, - onDemandAssignmentProvider: { - palletVersion: () => {}, - }, - paras: { - paraLifecycles: { - entries: () => [], - }, - }, - }, -} as unknown as ApiPromise; - const coretimeApi = createApiWithAugmentations(kusamaCoretimeMetadata); +const kusamaApi = createApiWithAugmentations(kusamaMetadataV1003003); + const coretimeTypeFactory = new TypeFactory(coretimeApi); +const kusamaTypeFactory = new TypeFactory(kusamaApi); const regionsEntries = () => Promise.resolve().then(() => @@ -113,6 +85,108 @@ const workloadsEntries = () => }), ); +const parasLifeCyclesEntries = () => + Promise.resolve().then(() => + mockParasLifeCycles.map((parasLifeCycle) => { + const storageEntry = kusamaApi.query.paras.paraLifecycles; + const key = kusamaTypeFactory.storageKey(parasLifeCycle.key, 'U32', storageEntry); + return [ + key, + mockKusamaApiBlock26187139.registry.createType( + 'Option', + parasLifeCycle.value, + ), + ]; + }), + ); + +const coreDescriptorsEntries = () => + Promise.resolve().then(() => { + return mockCoreDescriptors.map((coreDescriptor) => { + const storageEntry = kusamaApi.query.coretimeAssignmentProvider.coreDescriptors; + const key = kusamaTypeFactory.storageKey(coreDescriptor.key, 'U32', storageEntry); + + const currentWork = mockKusamaApiBlock26187139.registry.createType( + 'Option', + coreDescriptor.value.currentWork, + ); + + const queue = mockKusamaApiBlock26187139.registry.createType( + 'Option', + coreDescriptor.value.queue, + ); + + return [ + key, + mockKusamaApiBlock26187139.registry.createType('PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor', { + ...coreDescriptor.value, + currentWork, + queue, + }), + ]; + }); + }); + +const coreSchedulesEntries = () => + Promise.resolve().then(() => { + return []; + }); + +const workplanEntries = () => + Promise.resolve().then(() => + mockWorkplans.map((workplan) => { + const storageEntry = coretimeApi.query.broker.workplan; + const key = coretimeTypeFactory.storageKey(workplan.key, 'StorageKey', storageEntry); + return [ + key, + mockKusamaCoretimeApiBlock26187139.registry.createType('Option>', workplan.value), + ]; + }), + ); + +const workplanMultiEntries = () => + Promise.resolve().then(() => { + const storageEntry = coretimeApi.query.broker.workplan; + const key = coretimeTypeFactory.storageKey(mockWorkplans[0].key, 'StorageKey', storageEntry); + return [ + key, + mockKusamaCoretimeApiBlock26187139.registry.createType( + 'Option>', + mockWorkplans[0].value, + ), + ]; + }); +const mockKusamaApi = { + ...mockKusamaApiBlock26187139, + at: (_hash: Hash) => mockKusamaApi, + consts: { + ...mockKusamaApiBlock26187139.consts, + coretime: { + brokerId: 1, + }, + onDemandAssignmentProvider: { + maxHistoricalRevenue: '50', + }, + }, + query: { + coretimeAssignmentProvider: { + coreSchedules: { + entries: coreSchedulesEntries, + }, + coreDescriptors: { + entries: coreDescriptorsEntries, + }, + palletVersion: () => Promise.resolve().then(() => '1'), + }, + onDemandAssignmentProvider: {}, + paras: { + paraLifecycles: { + entries: parasLifeCyclesEntries, + }, + }, + }, +} as unknown as ApiPromise; + const mockCoretimeApi = { ...mockKusamaCoretimeApiBlock26187139, at: (_hash: Hash) => mockCoretimeApi, @@ -163,21 +237,16 @@ const mockCoretimeApi = { }), ), workplan: { - entries: () => [], + entries: workplanEntries, }, workload: { - multi: () => [], + multi: workplanMultiEntries, entries: workloadsEntries, }, regions: { entries: regionsEntries, }, }, - paras: { - paraLifecycles: { - entries: () => [], - }, - }, }, } as unknown as ApiPromise; @@ -281,10 +350,28 @@ describe('CoretimeService', () => { }); describe('getCores', () => { - it('should get workloads', async () => { + it('should get cores for coretime chain', async () => { const cores = await CoretimeServiceAtCoretimeChain.getCoretimeCores(blockHash26187139); expect(cores.cores).toHaveLength(2); expect(cores.at).toHaveProperty('hash'); + expect(cores.cores && cores.cores[0]).toHaveProperty('coreId'); + expect(cores.cores && cores.cores[0]).toHaveProperty('regions'); + expect(cores.cores && cores.cores[0]).toHaveProperty('taskId'); + }); + + it('should get cores for relay chain', async () => { + const cores = await CoretimeServiceAtRelayChain.getCoretimeCores(blockHash26187139); + console.log(cores); + expect(cores.cores).toHaveLength(2); + expect(cores.at).toHaveProperty('hash'); + expect(cores.cores && cores.cores[0]).toHaveProperty('paraId'); + expect(cores.cores && cores.cores[0]).toHaveProperty('type'); + expect(cores.cores && cores.cores[0]).toHaveProperty('info'); + const coresData = cores.cores; + if (coresData && 'info' in coresData[0]) { + expect(coresData[0].info).toHaveProperty('currentWork'); + expect(coresData[0].info.currentWork).toHaveProperty('assignments'); + } }); }); }); diff --git a/src/services/coretime/CoretimeService.ts b/src/services/coretime/CoretimeService.ts index ecf1c93e8..44b9af474 100644 --- a/src/services/coretime/CoretimeService.ts +++ b/src/services/coretime/CoretimeService.ts @@ -19,7 +19,7 @@ // import { QueryableModuleStorage } from '@polkadot/api/types'; import { ApiDecoration, QueryableModuleStorage } from '@polkadot/api/types'; -import { Option, StorageKey, U16, U32, u32, Vec } from '@polkadot/types'; +import { Option, StorageKey, U16, U32, Vec } from '@polkadot/types'; import { BlockHash, ParaId } from '@polkadot/types/interfaces'; import { PalletBrokerConfigRecord, @@ -182,11 +182,11 @@ export class CoretimeService extends AbstractService { private getAndDecodeCoreDescriptors = async (api: ApiDecoration<'promise'>): Promise => { const coreDescriptors = await api.query.coretimeAssignmentProvider.coreDescriptors.entries(); - const descriptors = coreDescriptors as unknown as [ - StorageKey<[u32]>, + StorageKey<[U32]>, PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, ][]; + return descriptors.map((descriptor) => extractCoreDescriptorInfo(descriptor[0], descriptor[1])); }; @@ -424,13 +424,13 @@ export class CoretimeService extends AbstractService { hash, height: blockNumber.toString(10), }, - coreDescriptors: descriptorsWithParas, + cores: descriptorsWithParas, coreSchedules: schedules, }; } else { const [workload, workplan, leases, reservations, regions] = await Promise.all([ this.getAndDecodeWorkload(historicApi, coreId ? parseInt(coreId, 10) : undefined), - coreId ? this.getAndDecodeWorkplan(historicApi, parseInt(coreId, 10)) : [], + this.getAndDecodeWorkplan(historicApi), this.getAndDecodeLeases(historicApi), this.getAndDecodeReservations(historicApi), this.getAndDecodeRegions(historicApi, coreId ? parseInt(coreId, 10) : undefined), diff --git a/src/services/coretime/util.ts b/src/services/coretime/util.ts index 733a605b4..90515c191 100644 --- a/src/services/coretime/util.ts +++ b/src/services/coretime/util.ts @@ -17,7 +17,7 @@ import { PolkadotRuntimeParachainsAssignerCoretimeWorkState, PolkadotRuntimeParachainsParasParaLifecycle, } from '@polkadot/types/lookup'; -import { Option, u32, Vec } from '@polkadot/types-codec'; +import { Option, U32, Vec } from '@polkadot/types-codec'; import { BN } from '@polkadot/util'; import { @@ -209,7 +209,7 @@ export function extractConfigInfo(info: Option): TConf } export function extractCoreDescriptorInfo( - _core: StorageKey<[u32]>, + _key: StorageKey<[U32]>, info: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, ): TCoreDescriptor { const currentWork: PolkadotRuntimeParachainsAssignerCoretimeWorkState | null = info?.currentWork.isSome @@ -219,7 +219,6 @@ export function extractCoreDescriptorInfo( ? info.queue.unwrap() : null; const assignments = currentWork?.assignments || []; - return { info: { currentWork: { diff --git a/src/services/test-helpers/mock/coretime/index.ts b/src/services/test-helpers/mock/coretime/index.ts index cbc653da6..aad2bd676 100644 --- a/src/services/test-helpers/mock/coretime/index.ts +++ b/src/services/test-helpers/mock/coretime/index.ts @@ -20,11 +20,49 @@ export const mockRegions = [ export const mockWorkloads = [ { key: '95', - value: { mask: '0xffffffffffffffffffff', assignment: { task: 2023 } }, + value: { mask: '0xffffffffffffffffffff', assignment: { task: 2032 } }, }, { key: '20', - value: { mask: '0xffffffffffffffffffff', assignment: { task: 2222 } }, + value: { mask: '0xffffffffffffffffffff', assignment: { task: 2007 } }, + }, +]; + +export const mockParasLifeCycles = [ + { + key: '2007', + value: 'Parathread', + }, + { + key: '2032', + value: 'Parachain', + }, +]; + +export const mockCoreDescriptors = [ + { + key: '10', + value: { + queue: null, + currentWork: { + assignments: [[{ task: 2007 }, { ratio: 57600, remaining: 57600 }]], + endHint: null, + pos: 1, + step: 57600, + }, + }, + }, + { + key: '11', + value: { + queue: null, + currentWork: { + assignments: [[{ task: 2032 }, { ratio: 57600, remaining: 57600 }]], + endHint: null, + pos: 1, + step: 57600, + }, + }, }, ]; @@ -34,7 +72,7 @@ export const potentialRenewalsMocks = [ value: { price: '55066361452', completion: { - Complete: [{ mask: '0xffffffffffffffffffff', assignment: { Task: '2274' } }], + Complete: [{ mask: '0xffffffffffffffffffff', assignment: { Task: '2007' } }], }, }, }, @@ -43,7 +81,7 @@ export const potentialRenewalsMocks = [ value: { price: '76754134107', completion: { - Complete: [{ mask: '0xffffffffffffffffffff', assignment: { Task: '2007' } }], + Complete: [{ mask: '0xffffffffffffffffffff', assignment: { Task: '2032' } }], }, }, }, @@ -51,11 +89,11 @@ export const potentialRenewalsMocks = [ export const mockLeases = [ { - task: '2000', + task: '2007', until: '340200', }, { - task: '2084', + task: '2032', until: '340200', }, ]; @@ -74,3 +112,14 @@ export const mockReservations = [ task: '1002', }, ]; + +export const mockWorkplans = [ + { + key: '0x4dcb50595177a3177648411a42aca0f5b20f0cdcf1dc08a3b45e596567ea076aefdd76257bb6014b780d05000800', + value: [{ mask: '0xffffffffffffffffffff', assignment: { Task: '2032' } }], + }, + { + key: '0x4dcb50595177a3177648411a42aca0f5b20f0cdcf1dc08a3b45e596567ea076af9bf2a8f54b8466c780d05001800', + value: [{ mask: '0xffffffffffffffffffff', assignment: { Task: '2007' } }], + }, +]; diff --git a/src/types/responses/Coretime.ts b/src/types/responses/Coretime.ts index 0e74ceb8c..46d2ce364 100644 --- a/src/types/responses/Coretime.ts +++ b/src/types/responses/Coretime.ts @@ -165,22 +165,24 @@ export interface ICoretimeInfo { export interface ICoretimeCores { at: IAt; - cores?: { - coreId: string; - taskId: string; - workload: TWorkloadInfo['info']; - type: { - condition: string; - details?: - | { - mask?: string; - } - | { - until?: number; - }; - }; - regions: TRegionInfo[]; - }[]; - coreDescriptors?: (TParaLifecycle & TCoreDescriptor)[]; + cores?: ( + | { + coreId: string; + taskId: string; + workload: TWorkloadInfo['info']; + type: { + condition: string; + details?: + | { + mask?: string; + } + | { + until?: number; + }; + }; + regions: TRegionInfo[]; + } + | (TParaLifecycle & TCoreDescriptor) + )[]; coreSchedules?: Record[]; }