Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nimbus author inherent mock #648

Merged
merged 3 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions configs/manta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
endpoint: wss://ws.manta.systems
mock-signature-host: true
block: ${env.MANTA_BLOCK_NUMBER}
db: ./db.sqlite

import-storage:
Sudo:
Key: dfbMFtQXqiKHH4d2y4CFcVQCpopqKcaEiYv2DCUpVCphoz8kB
System:
Account:
-
-
- dfbMFtQXqiKHH4d2y4CFcVQCpopqKcaEiYv2DCUpVCphoz8kB
- providers: 1
data:
free: '1000000000000000000000000'
14 changes: 14 additions & 0 deletions configs/tanssi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
endpoint: wss://fraa-dancebox-3001-rpc.a.dancebox.tanssi.network
mock-signature-host: true
block: ${env.TANSSI_BLOCK_NUMBER}
db: ./db.sqlite

import-storage:
Sudo:
Key: "0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"
System:
Account:
- - - "0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"
- providers: 1
data:
free: "10000000000000000000000000"
3 changes: 1 addition & 2 deletions packages/core/src/blockchain/block-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import { InherentProvider } from './inherent/index.js'
import { StorageLayer, StorageValueKind } from './storage-layer.js'
import { TaskCallResponse } from '../wasm-executor/index.js'
import { compactAddLength, hexToU8a, stringToHex, u8aConcat } from '@polkadot/util'
import { compactHex } from '../utils/index.js'
import { compactHex, getCurrentSlot } from '../utils/index.js'
import { defaultLogger, truncate } from '../logger.js'
import { getCurrentSlot } from '../utils/time-travel.js'

const logger = defaultLogger.child({ name: 'block-builder' })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { HexString } from '@polkadot/util/types'
import { Block } from '../../block.js'
import { BuildBlockParams } from '../../txpool.js'
import { InherentProvider } from '../index.js'
import { compactHex } from '../../../utils/index.js'

// Support for Nimbus Author Inherent
export class SetNimbusAuthorInherent implements InherentProvider {
Expand All @@ -15,6 +16,35 @@ export class SetNimbusAuthorInherent implements InherentProvider {
if (!meta.tx.authorInherent?.kickOffAuthorshipValidation) {
return []
}

// mock author inherent data and authorities noting data
const layer = newBlock.pushStorageLayer()

const accountType = meta.registry.hasType('NimbusPrimitivesNimbusCryptoPublic')
? 'NimbusPrimitivesNimbusCryptoPublic'
: 'AccountId'
const alice = meta.registry.hasType('NimbusPrimitivesNimbusCryptoPublic')
? '0x567b6ddb05396c0a83853b6f40d27450534c7963df8619b8c6064480c4db9703'
: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'
layer.set(compactHex(meta.query.authorInherent.author()), meta.registry.createType(accountType, alice).toHex())

if (meta.query.authoritiesNoting) {
layer.set(
compactHex(meta.query.authoritiesNoting.authorities()),
meta.registry.createType(`Vec<${accountType}>`, [alice]).toHex(),
)
layer.set(
compactHex(meta.query.authoritiesNoting.didSetOrchestratorAuthorityData()),
meta.registry.createType('bool', true).toHex(),
)
}
if (meta.query.parachainStaking) {
layer.set(
compactHex(meta.query.parachainStaking.selectedCandidates()),
meta.registry.createType(`Vec<${accountType}>`, [alice]).toHex(),
)
}

return [new GenericExtrinsic(meta.registry, meta.tx.authorInherent.kickOffAuthorshipValidation()).toHex()]
}
}
2 changes: 1 addition & 1 deletion packages/core/src/blockchain/inherent/timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Block } from '../block.js'
import { GenericExtrinsic } from '@polkadot/types'
import { HexString } from '@polkadot/util/types'
import { InherentProvider } from './index.js'
import { getCurrentTimestamp, getSlotDuration } from '../../utils/time-travel.js'
import { getCurrentTimestamp, getSlotDuration } from '../../utils/index.js'

export class SetTimestamp implements InherentProvider {
async createInherents(newBlock: Block): Promise<HexString[]> {
Expand Down
37 changes: 36 additions & 1 deletion packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BN, compactStripLength, hexToU8a, u8aToHex } from '@polkadot/util'
import { HexString } from '@polkadot/util/types'
import { Slot } from '@polkadot/types/interfaces'
import { StorageKey } from '@polkadot/types'
import { compactStripLength, u8aToHex } from '@polkadot/util'
import { getAuraSlotDuration } from '../wasm-executor/index.js'
import { hexAddPrefix, hexStripPrefix } from '@polkadot/util/hex'

import { Blockchain } from '../blockchain/index.js'
Expand Down Expand Up @@ -110,3 +112,36 @@ export const stripChildPrefix = (key: HexString) => {
if (!child) return key
return storageKey
}

// use raw key here because some chain did not expose those storage to metadata
const POTENTIAL_SLOT_KEYS = [
'0x1cb6f36e027abb2091cfb5110ab5087f06155b3cd9a8c9e5e9a23fd5dc13a5ed', // babe.currentSlot
'0x57f8dc2f5ab09467896f47300f04243806155b3cd9a8c9e5e9a23fd5dc13a5ed', // aura.currentSlot
'0xab2a8d5eca218f218c6fda6b1d22bb926bc171ab77f6a731a6e80c34ee1eda19', // authorInherent.highestSlotSeen
]

export const getCurrentSlot = async (chain: Blockchain) => {
const meta = await chain.head.meta
for (const key of POTENTIAL_SLOT_KEYS) {
const slotRaw = await chain.head.get(key)
if (slotRaw) {
return meta.registry.createType<Slot>('Slot', hexToU8a(slotRaw)).toNumber()
}
}
throw new Error('Cannot find current slot')
}

export const getCurrentTimestamp = async (chain: Blockchain) => {
const meta = await chain.head.meta
const timestamp = await chain.head.read('u64', meta.query.timestamp.now)
return timestamp?.toBigInt() ?? 0n
}

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.query.aura
? getAuraSlotDuration(await chain.head.wasm)
: 12_000
}
31 changes: 2 additions & 29 deletions packages/core/src/utils/time-travel.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,10 @@
import { BN, hexToU8a, u8aToHex } from '@polkadot/util'
import { BN, u8aToHex } from '@polkadot/util'
import { HexString } from '@polkadot/util/types'
import { Slot } from '@polkadot/types/interfaces'

import { Blockchain } from '../blockchain/index.js'
import { compactHex } from './index.js'
import { getAuraSlotDuration } from '../wasm-executor/index.js'
import { compactHex, getSlotDuration } from './index.js'
import { setStorage } from './set-storage.js'

export const getCurrentSlot = async (chain: Blockchain) => {
const meta = await chain.head.meta
// use raw key here because some chain did not expose those storage to metadata
const slotRaw = meta.consts.babe
? await chain.head.get('0x1cb6f36e027abb2091cfb5110ab5087f06155b3cd9a8c9e5e9a23fd5dc13a5ed') // babe.currentSlot
: await chain.head.get('0x57f8dc2f5ab09467896f47300f04243806155b3cd9a8c9e5e9a23fd5dc13a5ed') // aura.currentSlot
if (!slotRaw) throw new Error('Cannot find current slot')
return meta.registry.createType<Slot>('Slot', hexToU8a(slotRaw)).toNumber()
}

export const getCurrentTimestamp = async (chain: Blockchain) => {
const meta = await chain.head.meta
const timestamp = await chain.head.read('u64', meta.query.timestamp.now)
return timestamp?.toBigInt() ?? 0n
}

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.query.aura
? getAuraSlotDuration(await chain.head.wasm)
: 12_000
}

export const timeTravel = async (chain: Blockchain, timestamp: number) => {
const meta = await chain.head.meta

Expand Down
22 changes: 22 additions & 0 deletions packages/e2e/src/author-inherent-mock.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, it } from 'vitest'
import { setupContext } from '@acala-network/chopsticks-testing'

describe.runIf(process.env.CI || process.env.RUN_ALL)('Nimbus author inherent mock', async () => {
it('Manta build blocks', async () => {
const { dev, teardown } = await setupContext({
endpoint: 'wss://ws.manta.systems',
db: !process.env.RUN_TESTS_WITHOUT_DB ? 'e2e-tests-db.sqlite' : undefined,
})
await dev.newBlock({ count: 2 })
await teardown()
})

it('Tanssi build blocks', async () => {
const { dev, teardown } = await setupContext({
endpoint: 'wss://fraa-dancebox-3001-rpc.a.dancebox.tanssi.network',
db: !process.env.RUN_TESTS_WITHOUT_DB ? 'e2e-tests-db.sqlite' : undefined,
})
await dev.newBlock({ count: 2 })
await teardown()
})
})
3 changes: 2 additions & 1 deletion packages/e2e/src/time-travel.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest'
import { getCurrentTimestamp, getSlotDuration, timeTravel } from '@acala-network/chopsticks-core/utils/time-travel.js'
import { getCurrentTimestamp, getSlotDuration } from '@acala-network/chopsticks-core/utils/index.js'
import { timeTravel } from '@acala-network/chopsticks-core/utils/time-travel.js'

import networks from './networks.js'

Expand Down
Loading