diff --git a/src/executor.test.ts b/src/executor.test.ts index cd84fe47..850ab1d4 100644 --- a/src/executor.test.ts +++ b/src/executor.test.ts @@ -11,13 +11,16 @@ import { hrmpIngressChannelIndex, upgradeGoAheadSignal, } from './utils/proof' -import { calculateStateRoot, createProof, decodeProof, getRuntimeVersion } from './executor' +import { calculateStateRoot, createProof, decodeProof, getAuraSlotDuration, getRuntimeVersion } from './executor' + +const getCode = () => { + const code = String(readFileSync(path.join(__dirname, '../e2e/blobs/acala-runtime-2101.txt'))).trim() + expect(code.length).toBeGreaterThan(2) + return code as HexString +} describe('wasm', () => { it('get runtime version from wasm runtime', async () => { - const code = String(readFileSync(path.join(__dirname, '../e2e/blobs/acala-runtime-2101.txt'))).trim() - expect(code.length).toBeGreaterThan(2) - const expectedRuntimeVersion = { specName: 'acala', implName: 'acala', @@ -43,7 +46,7 @@ describe('wasm', () => { stateVersion: 0, } - expect(await getRuntimeVersion(code as HexString)).toMatchObject(expectedRuntimeVersion) + expect(await getRuntimeVersion(getCode())).toMatchObject(expectedRuntimeVersion) }) it('calculate state root', async () => { @@ -149,4 +152,9 @@ describe('wasm', () => { expect(decoded).toMatchSnapshot() expect(decoded[upgradeKey]).toBe('0x01') }) + + it('get aura slot duration', async () => { + const slotDuration = await getAuraSlotDuration(getCode(), new TypeRegistry()) + expect(slotDuration).eq(12000) + }) }) diff --git a/src/executor.ts b/src/executor.ts index f59ae2c1..6e6b98c3 100644 --- a/src/executor.ts +++ b/src/executor.ts @@ -12,6 +12,7 @@ import { global.WebSocket = WebSocket import { Block } from './blockchain/block' +import { Registry } from '@polkadot/types-codec/types' import { calculate_state_root, create_proof, @@ -21,7 +22,11 @@ import { } from '@acala-network/chopsticks-executor' import { defaultLogger, truncate, truncateStorageDiff } from './logger' -const logger = defaultLogger.child({ name: 'executor' }) +interface JsCallback { + getStorage: (key: HexString) => Promise + getPrefixKeys: (key: HexString) => Promise + getNextKey: (key: HexString) => Promise +} export type RuntimeVersion = { specName: string @@ -34,6 +39,8 @@ export type RuntimeVersion = { stateVersion: number } +const logger = defaultLogger.child({ name: 'executor' }) + export const getRuntimeVersion = async (code: HexString): Promise => { return get_runtime_version(code).then((version) => { version.specName = hexToString(version.specName) @@ -76,7 +83,7 @@ export const runTask = async ( mockSignatureHost: boolean allowUnresolvedImports: boolean }, - callback: JsCallback + callback: JsCallback = emptyTaskHandler ) => { logger.trace({ task: { ...task, wasm: truncate(task.wasm) } }, 'taskRun') const response = await run_task(task, callback) @@ -91,12 +98,6 @@ export const runTask = async ( return response } -interface JsCallback { - getStorage: (key: HexString) => Promise - getPrefixKeys: (key: HexString) => Promise - getNextKey: (key: HexString) => Promise -} - export const taskHandler = (block: Block): JsCallback => { return { getStorage: async function (key: HexString) { @@ -111,3 +112,29 @@ export const taskHandler = (block: Block): JsCallback => { }, } } + +export const emptyTaskHandler = { + getStorage: async function (_key: HexString) { + throw new Error('Method not implemented') + }, + getPrefixKeys: async function (_key: HexString) { + throw new Error('Method not implemented') + }, + getNextKey: async function (_key: HexString) { + throw new Error('Method not implemented') + }, +} + +export const getAuraSlotDuration = async (wasm: HexString, registry: Registry): Promise => { + const result = await runTask({ + wasm, + calls: [['AuraApi_slot_duration', '0x']], + storage: [], + mockSignatureHost: false, + allowUnresolvedImports: false, + }) + + if (!result.Call) throw new Error(result.Error) + const slotDuration = registry.createType('u64', hexToU8a(result.Call.result)).toNumber() + return slotDuration +} diff --git a/src/utils/time-travel.ts b/src/utils/time-travel.ts index 0772692f..bb85afd7 100644 --- a/src/utils/time-travel.ts +++ b/src/utils/time-travel.ts @@ -4,6 +4,7 @@ import { Slot } from '@polkadot/types/interfaces' import { Blockchain } from '../blockchain' import { compactHex } from '.' +import { getAuraSlotDuration } from '../executor' import { setStorage } from './set-storage' export const getCurrentSlot = async (chain: Blockchain) => { @@ -25,7 +26,7 @@ export const getSlotDuration = async (chain: Blockchain) => { const meta = await chain.head.meta return meta.consts.babe ? (meta.consts.babe.expectedBlockTime as any as BN).toNumber() - : (meta.consts.timestamp.minimumPeriod as any as BN).toNumber() * 2 + : getAuraSlotDuration(await chain.head.wasm, meta.registry) } export const timeTravel = async (chain: Blockchain, timestamp: number) => {