Browse Source

storage-node: workers api do not require passing sudo or lead account, read from chain instead

Mokhtar Naamani 4 years ago
parent
commit
02aaf50c3c

+ 4 - 0
storage-node/packages/cli/bin/cli.js

@@ -74,11 +74,15 @@ function load_identity (api, filename, passphrase) {
 const commands = {
   // add Alice well known account as storage provider
   'dev-init': async (api) => {
+    // dev accounts are automatically loaded, no need to add explicitly to keyring
+    // load_identity(api)
     let dev = require('./dev')
     return dev.init(api)
   },
   // Checks that the setup done by dev-init command was successful.
   'dev-check': async (api) => {
+    // dev accounts are automatically loaded, no need to add explicitly to keyring
+    // load_identity(api)
     let dev = require('./dev')
     return dev.check(api)
   },

+ 14 - 9
storage-node/packages/cli/bin/dev.js

@@ -57,7 +57,7 @@ const init = async (api) => {
   debug(`Ensuring Alice is sudo`)
 
   // make sure alice is sudo - indirectly checking this is a dev chain
-  const sudo = await api.api.query.sudo.key()
+  const sudo = await api.identities.getSudoAccount()
 
   if (!sudo.eq(alice)) {
     throw new Error('Setup requires Alice to be sudo. Are you sure you are running a devchain?')
@@ -90,24 +90,29 @@ const init = async (api) => {
 
   // Make alice the storage lead
   debug('Making Alice the storage Lead')
-  const leadOpeningId = await api.workers.dev_addStorageLeadOpening(alice)
+  const leadOpeningId = await api.workers.dev_addStorageLeadOpening()
   const leadApplicationId = await api.workers.dev_applyOnOpening(leadOpeningId, aliceMemberId, alice, alice)
-  api.workers.dev_beginLeadOpeningReview(leadOpeningId, alice)
-  api.workers.dev_fillLeadOpening(leadOpeningId, leadApplicationId, alice)
+  api.workers.dev_beginLeadOpeningReview(leadOpeningId)
+  await api.workers.dev_fillLeadOpening(leadOpeningId, leadApplicationId)
+
+  const leadAccount = await api.workers.getLeadRoleAccount()
+  if (!leadAccount.eq(alice)) {
+    throw new Error('Setting alice as lead failed')
+  }
 
   // Create a storage openinging, apply, start review, and fill opening
   debug(`Making ${ROLE_ACCOUNT_URI} account a storage provider`)
 
-  const openingId = await api.workers.dev_addStorageOpening(alice)
-  debug(`created new opening id ${openingId}`)
+  const openingId = await api.workers.dev_addStorageOpening()
+  debug(`created new storage opening: ${openingId}`)
 
   const applicationId = await api.workers.dev_applyOnOpening(openingId, aliceMemberId, alice, roleAccount)
-  debug(`created application id ${applicationId}`)
+  debug(`applied with application id: ${applicationId}`)
 
-  api.workers.dev_beginStorageOpeningReview(openingId, alice)
+  api.workers.dev_beginStorageOpeningReview(openingId)
 
   debug(`filling storage opening`)
-  const providerId = await api.workers.dev_fillStorageOpening(openingId, applicationId, alice)
+  const providerId = await api.workers.dev_fillStorageOpening(openingId, applicationId)
 
   debug(`Assigned storage provider id: ${providerId}`)
 

+ 4 - 0
storage-node/packages/runtime-api/identities.js

@@ -225,6 +225,10 @@ class IdentitiesApi {
 
     return pair
   }
+
+  getSudoAccount() {
+    return this.base.api.query.sudo.key()
+  }
 }
 
 module.exports = {

+ 3 - 2
storage-node/packages/runtime-api/index.js

@@ -157,9 +157,10 @@ class RuntimeApi {
    * callback is invoked with matching events.
    */
   async signAndSend (accountId, tx, attempts, subscribed, callback) {
-    // Prepare key
-    const from_key = this.identities.keyring.getPair(accountId)
+    accountId = this.identities.keyring.encodeAddress(accountId)
 
+    // Key must be unlocked
+    const from_key = this.identities.keyring.getPair(accountId)
     if (from_key.isLocked) {
       throw new Error('Must unlock key before using it to sign!')
     }

+ 29 - 26
storage-node/packages/runtime-api/workers.js

@@ -125,6 +125,16 @@ class WorkersApi {
     return { ids, providers }
   }
 
+  async getLeadRoleAccount() {
+    const currentLead = await this.base.api.query.storageWorkingGroup.currentLead()
+    if (currentLead.isSome) {
+      const leadWorkerId = currentLead.unwrap()
+      const worker = await this.base.api.query.storageWorkingGroup.workerById(leadWorkerId)
+      return worker[0].role_account_id
+    }
+    return null
+  }
+
   // Helper methods below don't really belong in the colossus runtime api library.
   // They are only used by the dev-init command in the cli to setup a development environment
 
@@ -132,26 +142,26 @@ class WorkersApi {
    * Add a new storage group opening using the lead account. Returns the
    * new opening id.
    */
-  async dev_addStorageOpening(leadAccount) {
+  async dev_addStorageOpening() {
     const openTx = this.dev_makeAddOpeningTx('Worker')
-    return this.dev_submitAddOpeningTx(openTx, leadAccount)
+    return this.dev_submitAddOpeningTx(openTx, await this.getLeadRoleAccount())
   }
 
   /*
    * Add a new storage working group lead opening using sudo account. Returns the
    * new opening id.
    */
-  async dev_addStorageLeadOpening(sudoAccount) {
+  async dev_addStorageLeadOpening() {
     const openTx = this.dev_makeAddOpeningTx('Leader')
     const sudoTx = this.base.api.tx.sudo.sudo(openTx)
-    return this.dev_submitAddOpeningTx(sudoTx, sudoAccount)
+    return this.dev_submitAddOpeningTx(sudoTx, await this.base.identities.getSudoAccount())
   }
 
   /*
    * Constructs an addOpening tx of openingType
    */
   dev_makeAddOpeningTx(openingType) {
-    const openTx = this.base.api.tx.storageWorkingGroup.addOpening(
+    return this.base.api.tx.storageWorkingGroup.addOpening(
       'CurrentBlock',
       {
         application_rationing_policy: {
@@ -163,8 +173,6 @@ class WorkersApi {
       'dev-opening',
       openingType
     )
-
-    return openTx
   }
 
   /*
@@ -172,13 +180,11 @@ class WorkersApi {
    * the OpeningId from the resulting event.
    */
   async dev_submitAddOpeningTx(tx, senderAccount) {
-    const openingId = await this.base.signAndSendThenGetEventResult(senderAccount, tx, {
+    return this.base.signAndSendThenGetEventResult(senderAccount, tx, {
       eventModule: 'storageWorkingGroup',
       eventName: 'OpeningAdded',
       eventProperty: 'OpeningId'
     })
-
-    return openingId
   }
 
   /*
@@ -188,30 +194,29 @@ class WorkersApi {
     const applyTx = this.base.api.tx.storageWorkingGroup.applyOnOpening(
       memberId, openingId, roleAccount, null, null, `colossus-${memberId}`
     )
-    const applicationId = await this.base.signAndSendThenGetEventResult(memberAccount, applyTx, {
+
+    return this.base.signAndSendThenGetEventResult(memberAccount, applyTx, {
       eventModule: 'storageWorkingGroup',
       eventName: 'AppliedOnOpening',
       eventProperty: 'ApplicationId'
     })
-
-    return applicationId
   }
 
   /*
    * Move lead opening to review state using sudo account
    */
-  async dev_beginLeadOpeningReview(openingId, sudoAccount) {
+  async dev_beginLeadOpeningReview(openingId) {
     const beginReviewTx = this.dev_makeBeginOpeningReviewTx(openingId)
     const sudoTx = this.base.api.tx.sudo.sudo(beginReviewTx)
-    return this.base.signAndSend(sudoAccount, sudoTx)
+    return this.base.signAndSend(await this.base.identities.getSudoAccount(), sudoTx)
   }
 
   /*
    * Move a storage opening to review state using lead account
    */
-  async dev_beginStorageOpeningReview(openingId, leadAccount) {
+  async dev_beginStorageOpeningReview(openingId) {
     const beginReviewTx = this.dev_makeBeginOpeningReviewTx(openingId)
-    return this.base.signAndSend(leadAccount, beginReviewTx)
+    return this.base.signAndSend(await this.getLeadRoleAccount(), beginReviewTx)
   }
 
   /*
@@ -224,19 +229,20 @@ class WorkersApi {
   /*
    * Fill a lead opening, return the assigned worker id, using the sudo account
    */
-  async dev_fillLeadOpening(openingId, applicationId, sudoAccount) {
+  async dev_fillLeadOpening(openingId, applicationId) {
     const fillTx = this.dev_makeFillOpeningTx(openingId, applicationId)
     const sudoTx = this.base.api.tx.sudo.sudo(fillTx)
-    const filled = await this.dev_submitFillOpeningTx(sudoAccount, sudoTx)
+    const filled = await this.dev_submitFillOpeningTx(
+      await this.base.identities.getSudoAccount(), sudoTx)
     return getWorkerIdFromApplicationIdToWorkerIdMap(filled, applicationId)
   }
 
   /*
    * Fill a storage opening, return the assigned worker id, using the lead account
    */
-  async dev_fillStorageOpening(openingId, applicationId, leadAccount) {
+  async dev_fillStorageOpening(openingId, applicationId) {
     const fillTx = this.dev_makeFillOpeningTx(openingId, applicationId)
-    const filled = await this.dev_submitFillOpeningTx(leadAccount, fillTx)
+    const filled = await this.dev_submitFillOpeningTx(await this.getLeadRoleAccount(), fillTx)
     return getWorkerIdFromApplicationIdToWorkerIdMap(filled, applicationId)
   }
 
@@ -244,21 +250,18 @@ class WorkersApi {
    * Constructs a FillOpening transaction
    */
   dev_makeFillOpeningTx(openingId, applicationId) {
-    const fillTx = this.base.api.tx.storageWorkingGroup.fillOpening(openingId, [applicationId], null)
-    return fillTx
+    return this.base.api.tx.storageWorkingGroup.fillOpening(openingId, [applicationId], null)
   }
 
   /*
    * Dispatches a fill opening tx and returns a map of the application id to their new assigned worker ids.
    */
   async dev_submitFillOpeningTx(senderAccount, tx) {
-    const filledMap = await this.base.signAndSendThenGetEventResult(senderAccount, tx, {
+    return this.base.signAndSendThenGetEventResult(senderAccount, tx, {
       eventModule: 'storageWorkingGroup',
       eventName: 'OpeningFilled',
       eventProperty: 'ApplicationIdToWorkerIdMap'
     })
-
-    return filledMap
   }
 }