Browse Source

storage-node: get provider id from chain when running dev server

Mokhtar Naamani 4 years ago
parent
commit
875ecb6d85

+ 29 - 30
storage-node/packages/cli/bin/dev.js

@@ -1,3 +1,7 @@
+/* eslint-disable no-console */
+
+'use strict'
+
 const debug = require('debug')('joystream:storage-cli:dev')
 
 function aliceKeyPair (api) {
@@ -8,12 +12,31 @@ function roleKeyPair (api) {
   return api.identities.keyring.addFromUri('//Colossus', null, 'sr25519')
 }
 
-// Setup Alice account on a developement chain that was
-// just launched as the storage lead, and a storage provider using the same
-// key as the role key
+const check = async (api) => {
+  const roleAccountId = roleKeyPair(api).address
+  const providerId = await api.workers.findProviderIdByRoleAccount(roleAccountId)
+
+  if (providerId === null) {
+    throw new Error('Dev storage provider not found on chain!')
+  }
+
+  console.log(`
+  Chain is setup with Dev storage provider:
+    providerId = ${providerId}
+    roleAccountId = ${roleAccountId}
+    roleKey = '//Colossus'
+  `)
+
+  return providerId
+}
+
+// Setup Alice account on a developement chain as
+// a member, storage lead, and a storage provider using a deterministic
+// development key for the role account
 const init = async (api) => {
   try {
-    return await check(api)
+    await check(api)
+    return
   } catch (err) {
     // setup is not correct we can try to run setup
   }
@@ -22,7 +45,7 @@ const init = async (api) => {
   const roleAccount = roleKeyPair(api).address
   const providerId = 0 // first assignable id
 
-  console.log(`Checking for dev chain...`)
+  debug(`Checking for dev chain...`)
 
   // make sure alice is sudo - indirectly checking this is a dev chain
   const sudo = await api.api.query.sudo.key()
@@ -37,7 +60,7 @@ const init = async (api) => {
   // Give role account some tokens to work with
   api.balances.transfer(alice, roleAccount, 100000)
 
-  debug('Registering Alice as Member')
+  console.log('Registering Alice as Member')
   // register alice as a member
   const aliceMemberId = await api.identities.registerMember(alice, {
     handle: 'alice'
@@ -96,30 +119,6 @@ const init = async (api) => {
   await api.discovery.setBootstrapEndpoints(alice, ['http://localhost:3001/'])
 }
 
-const check = async (api) => {
-  const providerId = 0 // the first provider id which would have been assigned in dev-init
-  const roleAccountId = roleKeyPair(api).address
-  const alice = aliceKeyPair(api).address
-
-  if (await api.workers.isRoleAccountOfStorageProvider(providerId, roleAccountId)) {
-    console.log(`
-      Chain is setup with Alice as a storage provider:
-      providerId = ${providerId}
-      roleAccount = "//Colossus"
-    `)
-  } else { throw new Error('Alice is not a storage provider') }
-
-  const currentLead = await api.api.query.storageWorkingGroup.currentLead()
-
-  if (currentLead.isSome && currentLead.unwrap().role_account_id.eq(alice)) {
-    console.log(`
-      Alice is correctly setup as the storage lead
-    `)
-  } else {
-    throw new Error('Alice is not the storage lead!')
-  }
-}
-
 module.exports = {
   init,
   check,

+ 5 - 10
storage-node/packages/colossus/bin/cli.js

@@ -1,4 +1,6 @@
 #!/usr/bin/env node
+/* es-lint disable*/
+
 'use strict'
 
 // Node requires
@@ -165,25 +167,18 @@ async function init_api_production ({ wsProvider, providerId, keyFile, passphras
 async function init_api_development () {
   // Load key information
   const { RuntimeApi } = require('@joystream/runtime-api')
-  const providerId = 0
 
   const wsProvider = 'ws://localhost:9944'
 
   const api = await RuntimeApi.create({
-    provider_url: wsProvider,
-    storageProviderId: providerId
+    provider_url: wsProvider
   })
 
   const dev = require('../../cli/bin/dev')
-  api.identities.useKeyPair(dev.roleKeyPair(api))
 
-  console.log(`Using ${api.identities.key.address} as role account`)
+  api.identities.useKeyPair(dev.roleKeyPair(api))
 
-  if (!await api.workers.isRoleAccountOfStorageProvider(api.storageProviderId, api.identities.key.address)) {
-    throw new Error('Development chain not configured correctly')
-  } else {
-    console.log('== Initialized runtime API for Development Server ==')
-  }
+  api.storageProviderId = await dev.check(api)
 
   return api
 }

+ 24 - 8
storage-node/packages/runtime-api/workers.js

@@ -34,6 +34,8 @@ class WorkersApi {
     return ret
   }
 
+
+  // eslint-disable-next-line class-methods-use-this, require-await
   async init () {
     debug('Init')
   }
@@ -42,10 +44,10 @@ class WorkersApi {
    * Check whether the given account and id represent an active storage provider
    */
   async isRoleAccountOfStorageProvider (storageProviderId, roleAccountId) {
-    storageProviderId = new BN(storageProviderId)
-    roleAccountId = this.base.identities.keyring.decodeAddress(roleAccountId)
-    const account = await this.storageProviderRoleAccount(storageProviderId)
-    return account && account.eq(roleAccountId)
+    const id = new BN(storageProviderId)
+    const roleAccount = this.base.identities.keyring.decodeAddress(roleAccountId)
+    const providerAccount = await this.storageProviderRoleAccount(id)
+    return providerAccount && providerAccount.eq(roleAccount)
   }
 
   async isStorageProvider (storageProviderId) {
@@ -61,9 +63,22 @@ class WorkersApi {
 
   // Returns a Worker instance or null if provider does not exist
   async storageWorkerByProviderId (storageProviderId) {
-    storageProviderId = new BN(storageProviderId)
+    const id = new BN(storageProviderId)
     const { providers } = await this.getAllProviders()
-    return providers[storageProviderId.toNumber()] || null
+    return providers[id.toNumber()] || null
+  }
+
+  async findProviderIdByRoleAccount (roleAccount) {
+    const { ids, providers } = await this.getAllProviders()
+
+    for (let i = 0; i < ids.length; i++) {
+      const id = ids[i]
+      if (providers[id].role_account.eq(roleAccount)) {
+        return id
+      }
+    }
+
+    return null
   }
 
   async getAllProviders () {
@@ -74,10 +89,11 @@ class WorkersApi {
     // So we iterate over possible ids which may or may not exist, by reading directly
     // from storage value
     const nextWorkerId = (await this.base.api.query.storageWorkingGroup.nextWorkerId()).toNumber()
-    let ids = []
-    let providers = {}
+    const ids = []
+    const providers = {}
     for (let id = 0; id < nextWorkerId; id++) {
       // We get back an Option. Will be None if value doesn't exist
+      // eslint-disable-next-line no-await-in-loop
       let value = await this.base.api.rpc.state.getStorage(
         this.base.api.query.storageWorkingGroup.workerById.key(id)
       )