Browse Source

storage-node: refactor discovery package

Mokhtar Naamani 4 years ago
parent
commit
5f5779ea78
2 changed files with 173 additions and 166 deletions
  1. 137 130
      storage-node/packages/discovery/discover.js
  2. 36 36
      storage-node/packages/discovery/publish.js

+ 137 - 130
storage-node/packages/discovery/discover.js

@@ -3,180 +3,187 @@ const debug = require('debug')('discovery::discover')
 const stripEndingSlash = require('@joystream/util/stripEndingSlash')
 
 const ipfs = require('ipfs-http-client')('localhost', '5001', { protocol: 'http' })
+const BN = require('bn.js')
 
-function inBrowser() {
-    return typeof window !== 'undefined'
+function inBrowser () {
+  return typeof window !== 'undefined'
 }
 
-var activeDiscoveries = {};
-var accountInfoCache = {};
-const CACHE_TTL = 60 * 60 * 1000;
+var activeDiscoveries = {}
+var accountInfoCache = {}
+const CACHE_TTL = 60 * 60 * 1000
 
 async function getIpnsIdentity (storageProviderId, runtimeApi) {
-    // lookup ipns identity from chain corresponding to storageProviderId
-    const info = await runtimeApi.discovery.getAccountInfo(storageProviderId)
-
-    if (info == null) {
-        // no identity found on chain for account
-        return null
-    } else {
-        return info.identity.toString()
-    }
+  storageProviderId = new BN(storageProviderId)
+  // lookup ipns identity from chain corresponding to storageProviderId
+  const info = await runtimeApi.discovery.getAccountInfo(storageProviderId)
+
+  if (info == null) {
+    // no identity found on chain for account
+    return null
+  } else {
+    return info.identity.toString()
+  }
 }
 
-async function discover_over_ipfs_http_gateway(storageProviderId, runtimeApi, gateway) {
-    let isActor = await runtimeApi.identities.isActor(storageProviderId)
+async function discover_over_ipfs_http_gateway (storageProviderId, runtimeApi, gateway) {
+  storageProviderId = new BN(storageProviderId)
+  let isProvider = await runtimeApi.workers.isStorageProvider(storageProviderId)
 
-    if (!isActor) {
-        throw new Error('Cannot discover non actor account service info')
-    }
+  if (!isProvider) {
+    throw new Error('Cannot discover non storage providers')
+  }
 
-    const identity = await getIpnsIdentity(actorAccountId, runtimeApi)
+  const identity = await getIpnsIdentity(storageProviderId, runtimeApi)
 
-    gateway = gateway || 'http://localhost:8080'
+  gateway = gateway || 'http://localhost:8080'
 
-    const url = `${gateway}/ipns/${identity}`
+  const url = `${gateway}/ipns/${identity}`
 
-    const response = await axios.get(url)
+  const response = await axios.get(url)
 
-    return response.data
+  return response.data
 }
 
-async function discover_over_joystream_discovery_service(actorAccountId, runtimeApi, discoverApiEndpoint) {
-    let isActor = await runtimeApi.identities.isActor(actorAccountId)
+async function discover_over_joystream_discovery_service (storageProviderId, runtimeApi, discoverApiEndpoint) {
+  storageProviderId = new BN(storageProviderId)
+  let isProvider = await runtimeApi.workers.isStorageProvider(storageProviderId)
 
-    if (!isActor) {
-        throw new Error('Cannot discover non actor account service info')
-    }
+  if (!isProvider) {
+    throw new Error('Cannot discover non storage providers')
+  }
 
-    const identity = await getIpnsIdentity(actorAccountId, runtimeApi)
+  const identity = await getIpnsIdentity(storageProviderId, runtimeApi)
 
-    if (identity == null) {
-        // dont waste time trying to resolve if no identity was found
-        throw new Error('no identity to resolve');
-    }
+  if (identity == null) {
+    // dont waste time trying to resolve if no identity was found
+    throw new Error('no identity to resolve')
+  }
 
-    if (!discoverApiEndpoint) {
-        // Use bootstrap nodes
-        let discoveryBootstrapNodes = await runtimeApi.discovery.getBootstrapEndpoints()
+  if (!discoverApiEndpoint) {
+    // Use bootstrap nodes
+    let discoveryBootstrapNodes = await runtimeApi.discovery.getBootstrapEndpoints()
 
-        if (discoveryBootstrapNodes.length) {
-            discoverApiEndpoint = stripEndingSlash(discoveryBootstrapNodes[0].toString())
-        } else {
-            throw new Error('No known discovery bootstrap nodes found on network');
-        }
+    if (discoveryBootstrapNodes.length) {
+      discoverApiEndpoint = stripEndingSlash(discoveryBootstrapNodes[0].toString())
+    } else {
+      throw new Error('No known discovery bootstrap nodes found on network')
     }
+  }
 
-    const url = `${discoverApiEndpoint}/discover/v0/${actorAccountId}`
+  const url = `${discoverApiEndpoint}/discover/v0/${storageProviderId.toNumber()}`
 
-    // should have parsed if data was json?
-    const response = await axios.get(url)
+  // should have parsed if data was json?
+  const response = await axios.get(url)
 
-    return response.data
+  return response.data
 }
 
-async function discover_over_local_ipfs_node(actorAccountId, runtimeApi) {
-    let isActor = await runtimeApi.identities.isActor(actorAccountId)
+async function discover_over_local_ipfs_node (storageProviderId, runtimeApi) {
+  storageProviderId = new BN(storageProviderId)
+  let isProvider = await runtimeApi.workers.isStorageProvider(storageProviderId)
 
-    if (!isActor) {
-        throw new Error('Cannot discover non actor account service info')
-    }
+  if (!isProvider) {
+    throw new Error('Cannot discover non actor account service info')
+  }
 
-    const identity = await getIpnsIdentity(actorAccountId, runtimeApi)
+  const identity = await getIpnsIdentity(storageProviderId, runtimeApi)
 
-    const ipns_address = `/ipns/${identity}/`
+  const ipns_address = `/ipns/${identity}/`
 
-    debug('resolved ipns to ipfs object')
-    let ipfs_name = await ipfs.name.resolve(ipns_address, {
-        recursive: false, // there should only be one indirection to service info file
-        nocache: false,
-    }) // this can hang forever!? can we set a timeout?
+  debug('resolved ipns to ipfs object')
+  let ipfs_name = await ipfs.name.resolve(ipns_address, {
+    recursive: false, // there should only be one indirection to service info file
+    nocache: false
+  }) // this can hang forever!? can we set a timeout?
 
-    debug('getting ipfs object', ipfs_name)
-    let data = await ipfs.get(ipfs_name) // this can sometimes hang forever!?! can we set a timeout?
+  debug('getting ipfs object', ipfs_name)
+  let data = await ipfs.get(ipfs_name) // this can sometimes hang forever!?! can we set a timeout?
 
-    // there should only be one file published under the resolved path
-    let content = data[0].content
+  // there should only be one file published under the resolved path
+  let content = data[0].content
 
-    // verify information and if 'discovery' service found
-    // add it to our list of bootstrap nodes
+  // verify information and if 'discovery' service found
+  // add it to our list of bootstrap nodes
 
-    // TODO cache result or flag
-    return JSON.parse(content)
+  // TODO cache result or flag
+  return JSON.parse(content)
 }
 
-async function discover (actorAccountId, runtimeApi, useCachedValue = false, maxCacheAge = 0) {
-    const id = actorAccountId.toString();
-    const cached = accountInfoCache[id];
-
-    if (cached && useCachedValue) {
-        if (maxCacheAge > 0) {
-            // get latest value
-            if (Date.now() > (cached.updated + maxCacheAge)) {
-                return _discover(actorAccountId, runtimeApi);
-            }
-        }
-        // refresh if cache is stale, new value returned on next cached query
-        if (Date.now() > (cached.updated + CACHE_TTL)) {
-            _discover(actorAccountId, runtimeApi);
-        }
-        // return best known value
-        return cached.value;
-    } else {
-        return _discover(actorAccountId, runtimeApi);
+async function discover (storageProviderId, runtimeApi, useCachedValue = false, maxCacheAge = 0) {
+  storageProviderId = new BN(storageProviderId)
+  const id = storageProviderId.toNumber()
+  const cached = accountInfoCache[id]
+
+  if (cached && useCachedValue) {
+    if (maxCacheAge > 0) {
+      // get latest value
+      if (Date.now() > (cached.updated + maxCacheAge)) {
+        return _discover(storageProviderId, runtimeApi)
+      }
+    }
+    // refresh if cache is stale, new value returned on next cached query
+    if (Date.now() > (cached.updated + CACHE_TTL)) {
+      _discover(storageProviderId, runtimeApi)
     }
+    // return best known value
+    return cached.value
+  } else {
+    return _discover(storageProviderId, runtimeApi)
+  }
 }
 
-function createExternallyControlledPromise() {
-    let resolve, reject;
-    const promise = new Promise((_resolve, _reject) => {
-        resolve = _resolve;
-        reject = _reject;
-    });
-    return ({ resolve, reject, promise });
+function createExternallyControlledPromise () {
+  let resolve, reject
+  const promise = new Promise((_resolve, _reject) => {
+    resolve = _resolve
+    reject = _reject
+  })
+  return ({ resolve, reject, promise })
 }
 
-async function _discover(actorAccountId, runtimeApi) {
-    const id = actorAccountId.toString();
+async function _discover (storageProviderId, runtimeApi) {
+  storageProviderId = new BN(storageProviderId)
+  const id = storageProviderId.toNumber()
 
-    const discoveryResult = activeDiscoveries[id];
-    if (discoveryResult) {
-        debug('discovery in progress waiting for result for',id);
-        return discoveryResult
-    }
+  const discoveryResult = activeDiscoveries[id]
+  if (discoveryResult) {
+    debug('discovery in progress waiting for result for', id)
+    return discoveryResult
+  }
+
+  debug('starting new discovery for', id)
+  const deferredDiscovery = createExternallyControlledPromise()
+  activeDiscoveries[id] = deferredDiscovery.promise
 
-    debug('starting new discovery for', id);
-    const deferredDiscovery = createExternallyControlledPromise();
-    activeDiscoveries[id] = deferredDiscovery.promise;
-
-    let result;
-    try {
-        if (inBrowser()) {
-            result = await discover_over_joystream_discovery_service(actorAccountId, runtimeApi)
-        } else {
-            result = await discover_over_local_ipfs_node(actorAccountId, runtimeApi)
-        }
-        debug(result)
-        result = JSON.stringify(result)
-        accountInfoCache[id] = {
-            value: result,
-            updated: Date.now()
-        };
-
-        deferredDiscovery.resolve(result);
-        delete activeDiscoveries[id];
-        return result;
-    } catch (err) {
-        debug(err.message);
-        deferredDiscovery.reject(err);
-        delete activeDiscoveries[id];
-        throw err;
+  let result
+  try {
+    if (inBrowser()) {
+      result = await discover_over_joystream_discovery_service(storageProviderId, runtimeApi)
+    } else {
+      result = await discover_over_local_ipfs_node(storageProviderId, runtimeApi)
+    }
+    debug(result)
+    result = JSON.stringify(result)
+    accountInfoCache[id] = {
+      value: result,
+      updated: Date.now()
     }
+
+    deferredDiscovery.resolve(result)
+    delete activeDiscoveries[id]
+    return result
+  } catch (err) {
+    debug(err.message)
+    deferredDiscovery.reject(err)
+    delete activeDiscoveries[id]
+    throw err
+  }
 }
 
 module.exports = {
-    discover,
-    discover_over_joystream_discovery_service,
-    discover_over_ipfs_http_gateway,
-    discover_over_local_ipfs_node,
-}
+  discover,
+  discover_over_joystream_discovery_service,
+  discover_over_ipfs_http_gateway,
+  discover_over_local_ipfs_node
+}

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

@@ -3,51 +3,51 @@ const ipfs = ipfsClient('localhost', '5001', { protocol: 'http' })
 
 const debug = require('debug')('discovery::publish')
 
-const PUBLISH_KEY = 'self'; // 'services';
+const PUBLISH_KEY = 'self' // 'services'
 
-function bufferFrom(data) {
-    return Buffer.from(JSON.stringify(data), 'utf-8')
+function bufferFrom (data) {
+  return Buffer.from(JSON.stringify(data), 'utf-8')
 }
 
-function encodeServiceInfo(info) {
-    return bufferFrom({
-        serialized: JSON.stringify(info),
-        // signature: ''
-    })
+function encodeServiceInfo (info) {
+  return bufferFrom({
+    serialized: JSON.stringify(info)
+    // signature: ''
+  })
 }
 
 async function publish (service_info) {
-    const keys = await ipfs.key.list()
-    let services_key = keys.find((key) => key.name === PUBLISH_KEY)
-
-    // generate a new services key if not found
-    if (PUBLISH_KEY !== 'self' && !services_key) {
-        debug('generating ipns services key')
-        services_key = await ipfs.key.gen(PUBLISH_KEY, {
-          type: 'rsa',
-          size: 2048
-        });
-    }
-
-    if (!services_key) {
-        throw new Error('No IPFS publishing key available!')
-    }
-
-    debug('adding service info file to node')
-    const files = await ipfs.add(encodeServiceInfo(service_info))
-
-    debug('publishing...')
-    const published = await ipfs.name.publish(files[0].hash, {
-        key: PUBLISH_KEY,
-        resolve: false,
-        // lifetime: // string - Time duration of the record. Default: 24h
-        // ttl:      // string - Time duration this record should be cached
+  const keys = await ipfs.key.list()
+  let services_key = keys.find((key) => key.name === PUBLISH_KEY)
+
+  // generate a new services key if not found
+  if (PUBLISH_KEY !== 'self' && !services_key) {
+    debug('generating ipns services key')
+    services_key = await ipfs.key.gen(PUBLISH_KEY, {
+      type: 'rsa',
+      size: 2048
     })
+  }
+
+  if (!services_key) {
+    throw new Error('No IPFS publishing key available!')
+  }
+
+  debug('adding service info file to node')
+  const files = await ipfs.add(encodeServiceInfo(service_info))
+
+  debug('publishing...')
+  const published = await ipfs.name.publish(files[0].hash, {
+    key: PUBLISH_KEY,
+    resolve: false
+    // lifetime: // string - Time duration of the record. Default: 24h
+    // ttl:      // string - Time duration this record should be cached
+  })
 
-    debug(published)
-    return services_key.id;
+  debug(published)
+  return services_key.id
 }
 
 module.exports = {
-    publish
+  publish
 }