Browse Source

storage-node-v2: Improve bagId parsing.

Shamil Gadelshin 3 years ago
parent
commit
6312b2166d

+ 24 - 1
storage-node-v2/src/command-base/ApiCommandBase.ts

@@ -1,6 +1,11 @@
 import { Command, flags } from '@oclif/command'
 import { createApi } from '../services/runtime/api'
-import { getAccountFromJsonFile, getAlicePair, getAccountFromUri } from '../services/runtime/accounts'
+import {
+  getAccountFromJsonFile,
+  getAlicePair,
+  getAccountFromUri
+} from '../services/runtime/accounts'
+import { parseBagId } from '../services/helpers/bagTypes'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { ApiPromise } from '@polkadot/api'
 import logger from '../services/logger'
@@ -35,6 +40,24 @@ export default abstract class ApiCommandBase extends Command {
       char: 'y',
       description:
         'Account URI (optional). Has a priority over the keyfile and password flags. Could be overriden by ACCOUNT_URI environment variable.',
+  }
+
+  static extraFlags = {
+    bagId: flags.build({
+      parse: (value: string) => {
+        return parseBagId(value)
+      },
+      description: `Bag ID. Format: {bag_type}:{sub_type}:{id}.
+    - Bag types: 'static', 'dynamic'
+    - Sub types: 'static:council', 'static:wg', 'dynamic:member', 'dynamic:channel'
+    - Id:
+      - absent for 'static:council'
+      - working group name for 'static:wg'
+      - integer for 'dynamic:member' and 'dynamic:channel'
+    Examples:
+    - static:council
+    - static:wg:storage
+    - dynamic:member:4`,
     }),
   }
 

+ 5 - 23
storage-node-v2/src/commands/dev/verify-bag-id.ts

@@ -1,6 +1,5 @@
-import { flags } from '@oclif/command'
+import { Command, flags } from '@oclif/command'
 import ApiCommandBase from '../../command-base/ApiCommandBase'
-import { parseBagId } from '../../services/helpers/bagTypes'
 import logger from '../../services/logger'
 
 /**
@@ -11,37 +10,20 @@ import logger from '../../services/logger'
  * Should be run only during the development.
  * Shell command: "dev:verify-bag-id"
  */
-export default class DevVerifyBagId extends ApiCommandBase {
+export default class DevVerifyBagId extends Command {
   static description = 'The command verifies bag id supported by the storage node. Requires chain connection.'
 
   static flags = {
-    bagId: flags.string({
+    help: flags.help({ char: 'h' }),
+    bagId: ApiCommandBase.extraFlags.bagId({
       char: 'i',
       required: true,
-      description: `
-      Bag ID. Format: {bag_type}:{sub_type}:{id}.
-      - Bag types: 'static', 'dynamic'
-      - Sub types: 'static:council', 'static:wg', 'dynamic:member', 'dynamic:channel'
-      - Id: 
-        - absent for 'static:council'
-        - working group name for 'static:wg'
-        - integer for 'dynamic:member' and 'dynamic:channel'
-      Examples:
-      - static:council
-      - static:wg:storage
-      - dynamic:member:4
-      `,
     }),
-    ...ApiCommandBase.flags,
   }
 
   async run(): Promise<void> {
     const { flags } = this.parse(DevVerifyBagId)
 
-    const api = await this.getApi()
-    const parsedBagId = parseBagId(api, flags.bagId)
-
-    logger.info(`Correct bag id: ${flags.bagId}`)
-    logger.info(`Parsed: ${parsedBagId}`)
+    logger.info(`Parsed: ${flags.bagId}`)
   }
 }

+ 1 - 16
storage-node-v2/src/commands/leader/update-bag.ts

@@ -1,7 +1,6 @@
 import { flags } from '@oclif/command'
 import { updateStorageBucketsForBag } from '../../services/runtime/extrinsics'
 import ApiCommandBase from '../../command-base/ApiCommandBase'
-import { parseBagId } from '../../services/helpers/bagTypes'
 import logger from '../../services/logger'
 import ExitCodes from '../../command-base/ExitCodes'
 import _ from 'lodash'
@@ -43,22 +42,9 @@ export default class LeaderUpdateBag extends ApiCommandBase {
       description: 'ID of a bucket to remove from bag',
       default: [],
     }),
-    bagId: flags.string({
+    bagId: ApiCommandBase.extraFlags.bagId({
       char: 'i',
       required: true,
-      description: `
-      Bag ID. Format: {bag_type}:{sub_type}:{id}.
-      - Bag types: 'static', 'dynamic'
-      - Sub types: 'static:council', 'static:wg', 'dynamic:member', 'dynamic:channel'
-      - Id: 
-        - absent for 'static:council'
-        - working group name for 'static:wg'
-        - integer for 'dynamic:member' and 'dynamic:channel'
-      Examples:
-      - static:council
-      - static:wg:storage
-      - dynamic:member:4
-      `,
     }),
     ...ApiCommandBase.flags,
   }
@@ -78,7 +64,6 @@ export default class LeaderUpdateBag extends ApiCommandBase {
 
     const account = this.getAccount(flags)
     const api = await this.getApi()
-    const bagId = parseBagId(api, flags.bagId)
 
     const success = await updateStorageBucketsForBag(api, bagId, account, flags.add, flags.remove)
 

+ 8 - 7
storage-node-v2/src/commands/leader/update-dynamic-bag-policy.ts

@@ -44,13 +44,14 @@ export default class LeaderUpdateDynamicBagPolicy extends ApiCommandBase {
     const newNumber = flags.number
 
     const api = await this.getApi()
-    const dynamicBagType = parseDynamicBagType(api, flags.bagType)
-    const success = await updateNumberOfStorageBucketsInDynamicBagCreationPolicy(
-      api,
-      account,
-      dynamicBagType,
-      newNumber
-    )
+    const dynamicBagType = parseDynamicBagType(flags.bagType)
+    const success =
+      await updateNumberOfStorageBucketsInDynamicBagCreationPolicy(
+        api,
+        account,
+        dynamicBagType,
+        newNumber
+      )
 
     this.exitAfterRuntimeCall(success)
   }

+ 33 - 15
storage-node-v2/src/services/helpers/bagTypes.ts

@@ -1,6 +1,8 @@
 import { BagId, DynamicBagType, DynamicBagTypeKey, Static, Dynamic } from '@joystream/types/storage'
 import { WorkingGroup } from '@joystream/types/common'
-import { ApiPromise } from '@polkadot/api'
+import { registry } from '@joystream/types'
+import { createType } from '@polkadot/types'
+import { InterfaceTypes } from '@polkadot/types/types'
 import ExitCodes from '../../command-base/ExitCodes'
 import { CLIError } from '@oclif/errors'
 
@@ -26,8 +28,10 @@ export class BagIdValidationError extends CLIError {
  * @param bagType - dynamic bag type string
  * @returns The DynamicBagType instance.
  */
-export function parseDynamicBagType(api: ApiPromise, bagType: DynamicBagTypeKey): DynamicBagType {
-  return api.createType('DynamicBagType', bagType)
+export function parseDynamicBagType(
+  bagType: DynamicBagTypeKey
+): DynamicBagType {
+  return createJoystreamType('DynamicBagType', bagType)
 }
 
 /**
@@ -41,8 +45,8 @@ export function parseDynamicBagType(api: ApiPromise, bagType: DynamicBagTypeKey)
  * @param bagId - bag ID in string format
  * @returns The BagId instance.
  */
-export function parseBagId(api: ApiPromise, bagId: string): BagId {
-  const parser = new BagIdParser(api, bagId)
+export function parseBagId(bagId: string): BagId {
+  const parser = new BagIdParser(bagId)
 
   return parser.parse()
 }
@@ -52,12 +56,10 @@ export function parseBagId(api: ApiPromise, bagId: string): BagId {
  */
 class BagIdParser {
   bagId: string
-  api: ApiPromise
   bagIdParts: string[]
 
-  constructor(api: ApiPromise, bagId: string) {
+  constructor(bagId: string) {
     this.bagId = bagId
-    this.api = api
 
     this.bagIdParts = bagId.trim().toLowerCase().split(':')
 
@@ -89,8 +91,8 @@ class BagIdParser {
     // Try to construct static council bag ID.
     if (this.bagIdParts[1] === 'council') {
       if (this.bagIdParts.length === 2) {
-        const staticBagId: Static = this.api.createType('Static', 'Council')
-        const constructedBagId: BagId = this.api.createType('BagId', {
+        const staticBagId: Static = createJoystreamType('Static', 'Council')
+        const constructedBagId: BagId = createJoystreamType('BagId', {
           'Static': staticBagId,
         })
 
@@ -106,11 +108,14 @@ class BagIdParser {
 
         for (const group of groups) {
           if (group.toLowerCase() === actualGroup) {
-            const workingGroup: WorkingGroup = this.api.createType('WorkingGroup', group)
-            const staticBagId: Static = this.api.createType('Static', {
+            const workingGroup: WorkingGroup = createJoystreamType(
+              'WorkingGroup',
+              group
+            )
+            const staticBagId: Static = createJoystreamType('Static', {
               'WorkingGroup': workingGroup,
             })
-            const constructedBagId: BagId = this.api.createType('BagId', {
+            const constructedBagId: BagId = createJoystreamType('BagId', {
               'Static': staticBagId,
             })
 
@@ -142,8 +147,11 @@ class BagIdParser {
             const dynamic = {} as Record<DynamicBagTypeKey, number>
             dynamic[dynamicBagType as DynamicBagTypeKey] = parsedId
 
-            const dynamicBagId: Dynamic = this.api.createType('Dynamic', dynamic)
-            const constructedBagId: BagId = this.api.createType('BagId', {
+            const dynamicBagId: Dynamic = createJoystreamType(
+              'Dynamic',
+              dynamic
+            )
+            const constructedBagId: BagId = createJoystreamType('BagId', {
               'Dynamic': dynamicBagId,
             })
 
@@ -156,3 +164,13 @@ class BagIdParser {
     throw new BagIdValidationError(`Invalid dynamic bagId: ${this.bagId}`)
   }
 }
+
+/**
+ * Creates Joystream type using type registry.
+ */
+function createJoystreamType<T extends keyof InterfaceTypes>(
+  type: T,
+  value: unknown
+): InterfaceTypes[T] {
+  return createType(registry, type, value)
+}