Browse Source

storage-node: docs and minor refactoring of external promise util

Mokhtar Naamani 4 years ago
parent
commit
6f31b0b9cb

+ 2 - 15
storage-node/packages/discovery/discover.js

@@ -4,6 +4,7 @@ const stripEndingSlash = require('@joystream/util/stripEndingSlash')
 
 const ipfs = require('ipfs-http-client')('localhost', '5001', { protocol: 'http' })
 const BN = require('bn.js')
+const { newExternallyControlledPromise } = require('@joystream/util/externalPromise')
 
 /**
  * Determines if code is running in a browser by testing for the global window object
@@ -209,20 +210,6 @@ async function discover (storageProviderId, runtimeApi, useCachedValue = false,
   }
 }
 
-/**
- * Returns an object that contains a Promise and exposes its handlers, ie. resolve and reject methods
- * so it can be fulfilled 'externally'. This is a bit of a hack, but most useful application is when
- * concurrent async operations are initiated that are all waiting on the same result value.
- */
-function createExternallyControlledPromise () {
-  let resolve, reject
-  const promise = new Promise((_resolve, _reject) => {
-    resolve = _resolve
-    reject = _reject
-  })
-  return ({ resolve, reject, promise })
-}
-
 /**
  * Internal method that handles concurrent discoveries and caching of results. Will
  * select the appropriate discovery protocol based on wether we are in a browser environemtn or not.
@@ -242,7 +229,7 @@ async function _discover (storageProviderId, runtimeApi) {
   }
 
   debug('starting new discovery for', id)
-  const deferredDiscovery = createExternallyControlledPromise()
+  const deferredDiscovery = newExternallyControlledPromise()
   activeDiscoveries[id] = deferredDiscovery.promise
 
   let result

+ 2 - 2
storage-node/packages/discovery/publish.js

@@ -13,7 +13,7 @@ const PUBLISH_KEY = 'self'
 /**
  * Applies JSON serialization on the data object and converts the utf-8
  * string to a Buffer.
- * @param {object} data
+ * @param {object} data - json object
  * @returns {Buffer}
  */
 function bufferFrom (data) {
@@ -23,7 +23,7 @@ function bufferFrom (data) {
 /**
  * Encodes the service info into a standard format see. /storage-node/docs/json-signing.md
  * To be able to add a signature over the json data. Signing is not currently implemented.
- * @param {object} info - the service information
+ * @param {object} info - json object
  * @returns {Buffer}
  */
 function encodeServiceInfo (info) {

+ 16 - 10
storage-node/packages/runtime-api/assets.js

@@ -27,7 +27,7 @@ class AssetsApi {
   }
 
   /*
-   * Create a data object.
+   * Create and return a data object.
    */
   async createDataObject (accountId, memberId, contentId, doTypeId, size, ipfsCid) {
     contentId = parseContentId(contentId)
@@ -40,7 +40,7 @@ class AssetsApi {
   }
 
   /*
-   * Return the Data Object for a CID
+   * Return the Data Object for a contendId
    */
   async getDataObject (contentId) {
     contentId = parseContentId(contentId)
@@ -48,10 +48,10 @@ class AssetsApi {
   }
 
   /*
-   * Verify the liaison state for a DO:
-   * - Check the content ID has a DO
+   * Verify the liaison state for a DataObject:
+   * - Check the content ID has a DataObject
    * - Check the storageProviderId is the liaison
-   * - Check the liaison state is pending
+   * - Check the liaison state is Pending
    *
    * Each failure errors out, success returns the data object.
    */
@@ -78,7 +78,7 @@ class AssetsApi {
   }
 
   /*
-   * Changes a data object liaison judgement.
+   * Sets the data object liaison judgement to Accepted
    */
   async acceptContent (providerAccoundId, storageProviderId, contentId) {
     contentId = parseContentId(contentId)
@@ -87,7 +87,7 @@ class AssetsApi {
   }
 
   /*
-   * Changes a data object liaison judgement.
+   * Sets the data object liaison judgement to Rejected
    */
   async rejectContent (providerAccountId, storageProviderId, contentId) {
     contentId = parseContentId(contentId)
@@ -96,7 +96,7 @@ class AssetsApi {
   }
 
   /*
-   * Create storage relationship
+   * Creates storage relationship for a data object and provider
    */
   async createStorageRelationship (providerAccountId, storageProviderId, contentId, callback) {
     contentId = parseContentId(contentId)
@@ -107,7 +107,7 @@ class AssetsApi {
   }
 
   /*
-   * Get storage relationship for contentId
+   * Gets storage relationship for contentId for the given provider
    */
   async getStorageRelationshipAndId (storageProviderId, contentId) {
     contentId = parseContentId(contentId)
@@ -125,6 +125,9 @@ class AssetsApi {
     return {}
   }
 
+  /*
+   * Creates storage relationship for a data object and provider and returns the relationship id
+   */
   async createAndReturnStorageRelationship (providerAccountId, storageProviderId, contentId) {
     contentId = parseContentId(contentId)
     return new Promise(async (resolve, reject) => {
@@ -141,7 +144,7 @@ class AssetsApi {
   }
 
   /*
-   * Toggle ready state for DOSR.
+   * Set the ready state for a data object storage relationship to the new value
    */
   async toggleStorageRelationshipReady (providerAccountId, storageProviderId, dosrId, ready) {
     var tx = ready
@@ -150,6 +153,9 @@ class AssetsApi {
     return this.base.signAndSend(providerAccountId, tx)
   }
 
+  /*
+   * Returns array of know content ids
+   */
   async getKnownContentIds () {
     return this.base.api.query.dataDirectory.knownContentIds()
   }

+ 1 - 1
storage-node/packages/runtime-api/discovery.js

@@ -25,7 +25,7 @@ class DiscoveryApi {
   }
 
   /*
-   * Set Bootstrap endpoints
+   * Set Bootstrap endpoints, requires the sudo account to be provided and unlocked
    */
   async setBootstrapEndpoints (sudoAccount, endpoints) {
     const tx = this.base.api.tx.discovery.setBootstrapEndpoints(endpoints)

+ 14 - 6
storage-node/packages/runtime-api/identities.js

@@ -119,7 +119,7 @@ class IdentitiesApi {
   }
 
   /*
-   * Return true if the account is a member
+   * Return true if the account is a root account of a member
    */
   async isMember (accountId) {
     const memberIds = await this.memberIdsOf(accountId) // return array of member ids
@@ -127,7 +127,7 @@ class IdentitiesApi {
   }
 
   /*
-   * Return the member IDs of an account
+   * Return all the member IDs of an account by the root account id
    */
   async memberIdsOf (accountId) {
     const decoded = this.keyring.decodeAddress(accountId)
@@ -135,7 +135,7 @@ class IdentitiesApi {
   }
 
   /*
-   * Return the first member ID of an account, or undefined if not a member.
+   * Return the first member ID of an account, or undefined if not a member root account.
    */
   async firstMemberIdOf (accountId) {
     const decoded = this.keyring.decodeAddress(accountId)
@@ -177,6 +177,10 @@ class IdentitiesApi {
     return filename
   }
 
+  /*
+   * Register account id with userInfo as a new member
+   * using default policy 0, returns new member id
+   */
   async registerMember (accountId, userInfo) {
     const tx = this.base.api.tx.members.buyMembership(0, userInfo)
 
@@ -187,13 +191,17 @@ class IdentitiesApi {
     })
   }
 
+  /*
+   * Injects a keypair and sets it as the default identity
+   */
   useKeyPair (keyPair) {
     this.key = this.keyring.addPair(keyPair)
   }
+
   /*
- * Create a new role key. If no name is given,
- * default to 'storage'.
- */
+   * Create a new role key. If no name is given,
+   * default to 'storage'.
+   */
   async createNewRoleKey (name) {
     name = name || 'storage-provider'
 

+ 5 - 12
storage-node/packages/runtime-api/index.js

@@ -29,6 +29,7 @@ const { WorkersApi } = require('@joystream/runtime-api/workers')
 const { AssetsApi } = require('@joystream/runtime-api/assets')
 const { DiscoveryApi } = require('@joystream/runtime-api/discovery')
 const AsyncLock = require('async-lock')
+const { newExternallyControlledPromise } = require('@joystream/util/externalPromise')
 
 /*
  * Initialize runtime (substrate) API and keyring.
@@ -270,8 +271,10 @@ class RuntimeApi {
     return finalizedPromise.promise
   }
 
-  // Sign and send a transaction expect event from
-  // module and return eventProperty from the event.
+  /*
+   * Sign and send a transaction expect event from
+   * module and return eventProperty from the event.
+   */
   async signAndSendThenGetEventResult (senderAccountId, tx, { eventModule, eventName, eventProperty }) {
     // event from a module,
     const subscribed = [[eventModule, eventName]]
@@ -292,16 +295,6 @@ class RuntimeApi {
 
 }
 
-function newExternallyControlledPromise () {
-  // externally controlled promise
-  let resolve, reject
-  const promise = new Promise((res, rej) => {
-    resolve = res
-    reject = rej
-  })
-  return ({resolve, reject, promise})
-}
-
 module.exports = {
   RuntimeApi
 }

+ 32 - 4
storage-node/packages/runtime-api/workers.js

@@ -20,7 +20,6 @@
 
 const debug = require('debug')('joystream:runtime:roles')
 const BN = require('bn.js')
-// const { createType } = require('@polkadot/types')
 const { Worker } = require('@joystream/types/lib/working-group')
 
 /*
@@ -41,7 +40,7 @@ class WorkersApi {
   }
 
   /*
-   * Check whether the given account and id represent an active storage provider
+   * Check whether the given account and id represent an enrolled storage provider
    */
   async isRoleAccountOfStorageProvider (storageProviderId, roleAccountId) {
     const id = new BN(storageProviderId)
@@ -50,24 +49,34 @@ class WorkersApi {
     return providerAccount && providerAccount.eq(roleAccount)
   }
 
+  /*
+   * Returns true if the provider id is enrolled
+   */
   async isStorageProvider (storageProviderId) {
     const worker = await this.storageWorkerByProviderId(storageProviderId)
     return worker !== null
   }
 
-  // Returns a provider's role account or null if provider doesn't exist
+  /*
+   * Returns a provider's role account or null if provider doesn't exist
+   */
   async storageProviderRoleAccount (storageProviderId) {
     const worker = await this.storageWorkerByProviderId(storageProviderId)
     return worker ? worker.role_account : null
   }
 
-  // Returns a Worker instance or null if provider does not exist
+  /*
+   * Returns a Worker instance or null if provider does not exist
+   */
   async storageWorkerByProviderId (storageProviderId) {
     const id = new BN(storageProviderId)
     const { providers } = await this.getAllProviders()
     return providers[id.toNumber()] || null
   }
 
+  /*
+   * Returns the the first found provider id with a role account or null if not found
+   */
   async findProviderIdByRoleAccount (roleAccount) {
     const { ids, providers } = await this.getAllProviders()
 
@@ -81,6 +90,9 @@ class WorkersApi {
     return null
   }
 
+  /*
+   * Returns the set of ids and Worker instances of providers enrolled on the network
+   */
   async getAllProviders () {
     // const workerEntries = await this.base.api.query.storageWorkingGroup.workerById()
     // can't rely on .isEmpty or isNone property to detect empty map
@@ -116,6 +128,9 @@ class WorkersApi {
   // Helper methods below don't really belong in the colossus api, they are here
   // mainly to be used by the dev-init command in the cli to setup a development environment
 
+  /*
+   * Sets the storage working group lead
+   */
   async dev_setLead(sudo, memberId, roleAccount) {
     const setLeadTx = this.base.api.tx.storageWorkingGroup.setLead(memberId, roleAccount)
     // make sudo call
@@ -125,6 +140,10 @@ class WorkersApi {
     )
   }
 
+  /*
+   * Add a new storage group worker opening using the lead account. Returns the
+   * new opening id.
+   */
   async dev_addWorkerOpening(leadAccount) {
     const openTx = this.base.api.tx.storageWorkingGroup.addWorkerOpening('CurrentBlock', {
       application_rationing_policy: {
@@ -143,6 +162,9 @@ class WorkersApi {
     return openingId
   }
 
+  /*
+   * Apply on an opening, returns the application id.
+   */
   async dev_applyOnOpening(openingId, memberId, memberAccount, roleAccount) {
     const applyTx = this.base.api.tx.storageWorkingGroup.applyOnWorkerOpening(
       memberId, openingId, roleAccount, null, null, `colossus-${memberId}`
@@ -156,11 +178,17 @@ class WorkersApi {
     return applicationId
   }
 
+  /*
+   * Move the opening into the review state
+   */
   async dev_beginOpeningReview(openingId, leadAccount) {
     const reviewTx = this.base.api.tx.storageWorkingGroup.beginWorkerApplicantReview(openingId)
     return this.base.signAndSend(leadAccount, reviewTx)
   }
 
+  /*
+   * Fill an opening, returns a map of the application id to their new assigned worker ids.
+   */
   async dev_fillOpeningWithSingleApplication(openingId, leadAccount, applicationId) {
     const fillTx = this.base.api.tx.storageWorkingGroup.fillWorkerOpening(openingId, [applicationId], null)
 

+ 19 - 0
storage-node/packages/util/externalPromise.js

@@ -0,0 +1,19 @@
+/**
+ * Returns an object that contains a Promise and exposes its handlers, ie. resolve and reject methods
+ * so it can be fulfilled 'externally'. This is a bit of a hack, but most useful application is when
+ * concurrent async operations are initiated that are all waiting on the same result value.
+ */
+function newExternallyControlledPromise () {
+    let resolve, reject
+
+    const promise = new Promise((res, rej) => {
+      resolve = res
+      reject = rej
+    })
+
+    return ({ resolve, reject, promise })
+}
+
+module.exports = {
+    newExternallyControlledPromise
+}