utils.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const { Text } = require('@polkadot/types')
  2. const fsPromises = require('fs/promises')
  3. const Path = require('path')
  4. const { encodeAddress } = require('@polkadot/keyring')
  5. const fs = require('fs')
  6. const axios = require('axios')
  7. function computeMedian(numbers) {
  8. const sorted = numbers.slice().sort((a, b) => a - b)
  9. const middle = Math.floor(sorted.length / 2)
  10. if (sorted.length % 2 === 0) {
  11. return (sorted[middle - 1] + sorted[middle]) / 2
  12. }
  13. return sorted[middle]
  14. }
  15. async function generateListOfDataObjectsToDownload(api, nrSmall, nrBig) {
  16. const dataObjects = await getAcceptedDataObjects(api)
  17. const dataObjectsSortedBySize = dataObjects.sort((dataObject) => dataObject.size_in_bytes)
  18. const smallFiles = dataObjectsSortedBySize.slice(0, nrSmall)
  19. const bigFiles = dataObjectsSortedBySize.slice(-nrBig)
  20. return smallFiles.concat(bigFiles).map((dataObject) => dataObject.contentId)
  21. }
  22. async function getWorkerEndpoint(api, workerId) {
  23. const value = await api.query.storageWorkingGroup.workerStorage(workerId)
  24. return new Text(api.registry, value).toString()
  25. }
  26. async function getAcceptedDataObjects(api) {
  27. let mapObjects = await api.query.dataDirectory.dataByContentId.entries()
  28. mapObjects = mapObjects.filter(([, dataObject]) => dataObject.liaison_judgement.type === 'Accepted')
  29. const ids = mapToContentId(mapObjects)
  30. const dataObjects = mapObjects.map(([, dataObject]) => dataObject)
  31. const dataObjectsWithIds = []
  32. for (let i = 0; i < dataObjects.length; i++) {
  33. dataObjects[i].contentId = ids[i]
  34. dataObjectsWithIds.push(dataObjects[i])
  35. }
  36. return dataObjectsWithIds
  37. }
  38. async function clearFolder(folder) {
  39. const files = await fsPromises.readdir(folder)
  40. for (const file of files) {
  41. await fsPromises.unlink(Path.join(folder, file))
  42. }
  43. }
  44. function makeAssetUrl(contentId, source) {
  45. source = removeEndingForwardSlash(source)
  46. return `${source}/asset/v0/${encodeAddress(contentId)}`
  47. }
  48. function mapToContentId(dataObjects) {
  49. return dataObjects.map(
  50. ([
  51. {
  52. args: [contentId],
  53. },
  54. ]) => contentId
  55. )
  56. }
  57. async function downloadFile(url, outputFolder, outputFilename) {
  58. const path = Path.join(outputFolder, outputFilename)
  59. const writer = fs.createWriteStream(path)
  60. const start = process.hrtime.bigint()
  61. const response = await axios({
  62. url,
  63. method: 'GET',
  64. responseType: 'stream',
  65. })
  66. response.data.pipe(writer)
  67. return new Promise((resolve, reject) => {
  68. writer.on('finish', () => {
  69. const end = process.hrtime.bigint()
  70. resolve(Number(end - start) / 1000000)
  71. })
  72. writer.on('error', reject)
  73. })
  74. }
  75. async function getActiveWorkersIds(api) {
  76. const ids = []
  77. const entries = await api.query.storageWorkingGroup.workerById.entries()
  78. entries.forEach(([storageKey, worker]) => {
  79. if (worker.is_active) {
  80. const id = storageKey.args[0].toNumber()
  81. ids.push(id)
  82. }
  83. })
  84. return ids
  85. }
  86. function removeEndingForwardSlash(url) {
  87. if (url.endsWith('/')) {
  88. return url.substring(0, url.length - 1)
  89. }
  90. return url.toString()
  91. }
  92. module.exports = {
  93. getWorkerEndpoint,
  94. generateListOfDataObjectsToDownload,
  95. makeAssetUrl,
  96. downloadFile,
  97. computeMedian,
  98. clearFolder,
  99. getActiveWorkersIds
  100. }