index.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. /*
  2. eslint-disable @typescript-eslint/naming-convention
  3. */
  4. import { EventContext, StoreContext } from '@joystream/hydra-common'
  5. import { Storage } from '../generated/types/storage'
  6. import {
  7. DistributionBucket,
  8. DistributionBucketFamily,
  9. DistributionBucketOperator,
  10. DistributionBucketOperatorMetadata,
  11. DistributionBucketOperatorStatus,
  12. NodeLocationMetadata,
  13. StorageBag,
  14. StorageBucket,
  15. StorageBucketOperatorStatusActive,
  16. StorageBucketOperatorStatusInvited,
  17. StorageBucketOperatorStatusMissing,
  18. StorageDataObject,
  19. StorageSystemParameters,
  20. GeoCoordinates,
  21. Video,
  22. } from 'query-node/dist/model'
  23. import BN from 'bn.js'
  24. import { getById, inconsistentState } from '../common'
  25. import {
  26. getVideoActiveStatus,
  27. updateVideoActiveCounters,
  28. IVideoActiveStatus,
  29. videoRelationsForCounters,
  30. unsetAssetRelations,
  31. } from '../content/utils'
  32. import {
  33. processDistributionBucketFamilyMetadata,
  34. processDistributionOperatorMetadata,
  35. processStorageOperatorMetadata,
  36. } from './metadata'
  37. import {
  38. createDataObjects,
  39. getStorageSystem,
  40. getStorageBucketWithOperatorMetadata,
  41. getBag,
  42. getDynamicBagId,
  43. getDynamicBagOwner,
  44. getDataObjectsInBag,
  45. getDynamicBag,
  46. getDistributionBucketFamilyWithMetadata,
  47. getDistributionBucketOperatorWithMetadata,
  48. distributionBucketId,
  49. distributionOperatorId,
  50. distributionBucketIdByFamilyAndIndex,
  51. } from './utils'
  52. import { In } from 'typeorm'
  53. // STORAGE BUCKETS
  54. export async function storage_StorageBucketCreated({ event, store }: EventContext & StoreContext): Promise<void> {
  55. const [
  56. bucketId,
  57. invitedWorkerId,
  58. acceptingNewBags,
  59. dataObjectSizeLimit,
  60. dataObjectCountLimit,
  61. ] = new Storage.StorageBucketCreatedEvent(event).params
  62. const storageBucket = new StorageBucket({
  63. id: bucketId.toString(),
  64. acceptingNewBags: acceptingNewBags.isTrue,
  65. dataObjectCountLimit: new BN(dataObjectCountLimit.toString()),
  66. dataObjectsSizeLimit: new BN(dataObjectSizeLimit.toString()),
  67. dataObjectsCount: new BN(0),
  68. dataObjectsSize: new BN(0),
  69. })
  70. if (invitedWorkerId.isSome) {
  71. const operatorStatus = new StorageBucketOperatorStatusInvited()
  72. operatorStatus.workerId = invitedWorkerId.unwrap().toNumber()
  73. storageBucket.operatorStatus = operatorStatus
  74. } else {
  75. storageBucket.operatorStatus = new StorageBucketOperatorStatusMissing()
  76. }
  77. await store.save<StorageBucket>(storageBucket)
  78. }
  79. export async function storage_StorageOperatorMetadataSet({ event, store }: EventContext & StoreContext): Promise<void> {
  80. const [bucketId, , metadataBytes] = new Storage.StorageOperatorMetadataSetEvent(event).params
  81. const storageBucket = await getStorageBucketWithOperatorMetadata(store, bucketId.toString())
  82. storageBucket.operatorMetadata = await processStorageOperatorMetadata(
  83. event,
  84. store,
  85. storageBucket.operatorMetadata,
  86. metadataBytes
  87. )
  88. await store.save<StorageBucket>(storageBucket)
  89. }
  90. export async function storage_StorageBucketStatusUpdated({ event, store }: EventContext & StoreContext): Promise<void> {
  91. const [bucketId, acceptingNewBags] = new Storage.StorageBucketStatusUpdatedEvent(event).params
  92. const storageBucket = await getById(store, StorageBucket, bucketId.toString())
  93. storageBucket.acceptingNewBags = acceptingNewBags.isTrue
  94. await store.save<StorageBucket>(storageBucket)
  95. }
  96. export async function storage_StorageBucketInvitationAccepted({
  97. event,
  98. store,
  99. }: EventContext & StoreContext): Promise<void> {
  100. const [bucketId, workerId, transactorAccountId] = new Storage.StorageBucketInvitationAcceptedEvent(event).params
  101. const storageBucket = await getById(store, StorageBucket, bucketId.toString())
  102. const operatorStatus = new StorageBucketOperatorStatusActive()
  103. operatorStatus.workerId = workerId.toNumber()
  104. operatorStatus.transactorAccountId = transactorAccountId.toString()
  105. storageBucket.operatorStatus = operatorStatus
  106. await store.save<StorageBucket>(storageBucket)
  107. }
  108. export async function storage_StorageBucketInvitationCancelled({
  109. event,
  110. store,
  111. }: EventContext & StoreContext): Promise<void> {
  112. const [bucketId] = new Storage.StorageBucketInvitationCancelledEvent(event).params
  113. const storageBucket = await getById(store, StorageBucket, bucketId.toString())
  114. const operatorStatus = new StorageBucketOperatorStatusMissing()
  115. storageBucket.operatorStatus = operatorStatus
  116. await store.save<StorageBucket>(storageBucket)
  117. }
  118. export async function storage_StorageBucketOperatorInvited({
  119. event,
  120. store,
  121. }: EventContext & StoreContext): Promise<void> {
  122. const [bucketId, workerId] = new Storage.StorageBucketOperatorInvitedEvent(event).params
  123. const storageBucket = await getById(store, StorageBucket, bucketId.toString())
  124. const operatorStatus = new StorageBucketOperatorStatusInvited()
  125. operatorStatus.workerId = workerId.toNumber()
  126. storageBucket.operatorStatus = operatorStatus
  127. await store.save<StorageBucket>(storageBucket)
  128. }
  129. export async function storage_StorageBucketOperatorRemoved({
  130. event,
  131. store,
  132. }: EventContext & StoreContext): Promise<void> {
  133. const [bucketId] = new Storage.StorageBucketInvitationCancelledEvent(event).params
  134. const storageBucket = await getById(store, StorageBucket, bucketId.toString())
  135. const operatorStatus = new StorageBucketOperatorStatusMissing()
  136. storageBucket.operatorStatus = operatorStatus
  137. await store.save<StorageBucket>(storageBucket)
  138. }
  139. export async function storage_StorageBucketsUpdatedForBag({
  140. event,
  141. store,
  142. }: EventContext & StoreContext): Promise<void> {
  143. const [bagId, addedBucketsSet, removedBucketsSet] = new Storage.StorageBucketsUpdatedForBagEvent(event).params
  144. // Get or create bag
  145. const storageBag = await getBag(store, bagId, ['storageBuckets'])
  146. const removedBucketsIds = Array.from(removedBucketsSet).map((id) => id.toString())
  147. const addedBucketsIds = Array.from(addedBucketsSet).map((id) => id.toString())
  148. storageBag.storageBuckets = (storageBag.storageBuckets || [])
  149. .filter((bucket) => !removedBucketsIds.includes(bucket.id))
  150. .concat(addedBucketsIds.map((id) => new StorageBucket({ id })))
  151. await store.save<StorageBag>(storageBag)
  152. }
  153. export async function storage_VoucherChanged({ event, store }: EventContext & StoreContext): Promise<void> {
  154. const [bucketId, voucher] = new Storage.VoucherChangedEvent(event).params
  155. const bucket = await getById(store, StorageBucket, bucketId.toString())
  156. bucket.dataObjectCountLimit = voucher.objectsLimit
  157. bucket.dataObjectsSizeLimit = voucher.sizeLimit
  158. bucket.dataObjectsCount = voucher.objectsUsed
  159. bucket.dataObjectsSize = voucher.sizeUsed
  160. await store.save<StorageBucket>(bucket)
  161. }
  162. export async function storage_StorageBucketVoucherLimitsSet({
  163. event,
  164. store,
  165. }: EventContext & StoreContext): Promise<void> {
  166. const [bucketId, sizeLimit, countLimit] = new Storage.StorageBucketVoucherLimitsSetEvent(event).params
  167. const bucket = await getById(store, StorageBucket, bucketId.toString())
  168. bucket.dataObjectsSizeLimit = sizeLimit
  169. bucket.dataObjectCountLimit = countLimit
  170. await store.save<StorageBucket>(bucket)
  171. }
  172. export async function storage_StorageBucketDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
  173. const [bucketId] = new Storage.StorageBucketDeletedEvent(event).params
  174. // TODO: Cascade remove on db level (would require changes in Hydra / comitting autogenerated files)
  175. const storageBucket = await store.get(StorageBucket, {
  176. where: { id: bucketId.toString() },
  177. relations: ['bags', 'bags.storageBuckets'],
  178. })
  179. if (!storageBucket) {
  180. inconsistentState(`Storage bucket by id ${bucketId.toString()} not found!`)
  181. }
  182. // Remove relations
  183. await Promise.all(
  184. (storageBucket.bags || []).map((bag) => {
  185. bag.storageBuckets = (bag.storageBuckets || []).filter((bucket) => bucket.id !== bucketId.toString())
  186. return store.save<StorageBag>(bag)
  187. })
  188. )
  189. await store.remove<StorageBucket>(storageBucket)
  190. }
  191. // DYNAMIC BAGS
  192. export async function storage_DynamicBagCreated({ event, store }: EventContext & StoreContext): Promise<void> {
  193. const [bagId, , storageBucketIdsSet, distributionBucketIdsSet] = new Storage.DynamicBagCreatedEvent(event).params
  194. const storageBag = new StorageBag({
  195. id: getDynamicBagId(bagId),
  196. owner: getDynamicBagOwner(bagId),
  197. storageBuckets: Array.from(storageBucketIdsSet).map((id) => new StorageBucket({ id: id.toString() })),
  198. distributionBuckets: Array.from(distributionBucketIdsSet).map(
  199. (id) => new DistributionBucket({ id: distributionBucketId(id) })
  200. ),
  201. })
  202. await store.save<StorageBag>(storageBag)
  203. }
  204. export async function storage_DynamicBagDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
  205. const [, bagId] = new Storage.DynamicBagDeletedEvent(event).params
  206. const storageBag = await getDynamicBag(store, bagId, ['objects'])
  207. await store.remove<StorageBag>(storageBag)
  208. }
  209. // DATA OBJECTS
  210. // Note: "Uploaded" here actually means "created" (the real upload happens later)
  211. export async function storage_DataObjectsUploaded({ event, store }: EventContext & StoreContext): Promise<void> {
  212. const [dataObjectIds, uploadParams, deletionPrize] = new Storage.DataObjectsUploadedEvent(event).params
  213. await createDataObjects(store, uploadParams, deletionPrize, dataObjectIds)
  214. }
  215. export async function storage_PendingDataObjectsAccepted({ event, store }: EventContext & StoreContext): Promise<void> {
  216. const [, , bagId, dataObjectIds] = new Storage.PendingDataObjectsAcceptedEvent(event).params
  217. const dataObjects = await getDataObjectsInBag(store, bagId, dataObjectIds, ['videoThumbnail', 'videoMedia'])
  218. // get ids of videos that are in relation with accepted data objects
  219. const notUniqueVideoIds = dataObjects
  220. .map((item) => [item.videoMedia?.id.toString(), item.videoThumbnail?.id.toString()])
  221. .flat()
  222. .filter((item) => item)
  223. const videoIds = [...new Set(notUniqueVideoIds)]
  224. // load videos
  225. const videosPre = await store.getMany(Video, {
  226. where: { id: In(videoIds) },
  227. relations: videoRelationsForCounters,
  228. })
  229. // remember if videos are fully active before data objects update
  230. const initialActiveStates = videosPre.map((video) => getVideoActiveStatus(video)).filter((item) => item)
  231. // accept storage data objects
  232. await Promise.all(
  233. dataObjects.map(async (dataObject, index) => {
  234. dataObject.isAccepted = true
  235. await store.save<StorageDataObject>(dataObject)
  236. })
  237. )
  238. /*
  239. This approach of reloading videos one by one is not optimal, but it is straightforward algorithm.
  240. This reduces otherwise complex situation caused by `store.get*` functions not return objects
  241. shared by mutliple entities (at least now). Because of that when updating for example
  242. `dataObject.videoThumnail.channel.activeVideoCounter` on dataObject A, this change is not
  243. reflected on `dataObject.videoMedia.channel.activeVideoCounter` on dataObject B.
  244. We can upgrade this algorithm in the future if this event mapping proves to have serious
  245. performance issues. In that case, a unit test for this mapping will be required.
  246. */
  247. // load relevant videos one by one and update related active-video-counters
  248. for (const initialActiveState of initialActiveStates) {
  249. // load refreshed version of videos and related entities (channel, channel category, category)
  250. const video = (await store.get(Video, {
  251. where: { id: initialActiveState.video.id.toString() },
  252. relations: videoRelationsForCounters,
  253. })) as Video
  254. await updateVideoActiveCounters(store, initialActiveState, getVideoActiveStatus(video))
  255. }
  256. }
  257. export async function storage_DataObjectsMoved({ event, store }: EventContext & StoreContext): Promise<void> {
  258. const [srcBagId, destBagId, dataObjectIds] = new Storage.DataObjectsMovedEvent(event).params
  259. const dataObjects = await getDataObjectsInBag(store, srcBagId, dataObjectIds)
  260. const destBag = await getBag(store, destBagId)
  261. await Promise.all(
  262. dataObjects.map(async (dataObject) => {
  263. dataObject.storageBag = destBag
  264. await store.save<StorageDataObject>(dataObject)
  265. })
  266. )
  267. }
  268. export async function storage_DataObjectsDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
  269. const [, bagId, dataObjectIds] = new Storage.DataObjectsDeletedEvent(event).params
  270. const dataObjects = await getDataObjectsInBag(store, bagId, dataObjectIds, [
  271. 'videoThumbnail',
  272. ...videoRelationsForCounters.map((item) => `videoThumbnail.${item}`),
  273. 'videoMedia',
  274. ...videoRelationsForCounters.map((item) => `videoMedia.${item}`),
  275. ])
  276. await Promise.all(
  277. dataObjects.map(async (dataObject) => {
  278. // remember if video is fully active before update
  279. const initialVideoActiveStatus =
  280. (dataObject.videoThumbnail && getVideoActiveStatus(dataObject.videoThumbnail)) ||
  281. (dataObject.videoMedia && getVideoActiveStatus(dataObject.videoMedia)) ||
  282. null
  283. await unsetAssetRelations(store, dataObject)
  284. // update video active counters
  285. if (initialVideoActiveStatus) {
  286. await updateVideoActiveCounters(store, initialVideoActiveStatus, undefined)
  287. }
  288. })
  289. )
  290. }
  291. // DISTRIBUTION FAMILY
  292. export async function storage_DistributionBucketFamilyCreated({
  293. event,
  294. store,
  295. }: EventContext & StoreContext): Promise<void> {
  296. const [familyId] = new Storage.DistributionBucketFamilyCreatedEvent(event).params
  297. const family = new DistributionBucketFamily({
  298. id: familyId.toString(),
  299. })
  300. await store.save<DistributionBucketFamily>(family)
  301. }
  302. export async function storage_DistributionBucketFamilyMetadataSet({
  303. event,
  304. store,
  305. }: EventContext & StoreContext): Promise<void> {
  306. const [familyId, metadataBytes] = new Storage.DistributionBucketFamilyMetadataSetEvent(event).params
  307. const family = await getDistributionBucketFamilyWithMetadata(store, familyId.toString())
  308. family.metadata = await processDistributionBucketFamilyMetadata(event, store, family.metadata, metadataBytes)
  309. await store.save<DistributionBucketFamily>(family)
  310. }
  311. export async function storage_DistributionBucketFamilyDeleted({
  312. event,
  313. store,
  314. }: EventContext & StoreContext): Promise<void> {
  315. const [familyId] = new Storage.DistributionBucketFamilyDeletedEvent(event).params
  316. const family = await getById(store, DistributionBucketFamily, familyId.toString())
  317. await store.remove(family)
  318. }
  319. // DISTRIBUTION BUCKET
  320. export async function storage_DistributionBucketCreated({ event, store }: EventContext & StoreContext): Promise<void> {
  321. const [familyId, acceptingNewBags, bucketId] = new Storage.DistributionBucketCreatedEvent(event).params
  322. const family = await getById(store, DistributionBucketFamily, familyId.toString())
  323. const bucket = new DistributionBucket({
  324. id: distributionBucketId(bucketId),
  325. bucketIndex: bucketId.distribution_bucket_index.toNumber(),
  326. acceptingNewBags: acceptingNewBags.valueOf(),
  327. distributing: true, // Runtime default
  328. family,
  329. })
  330. await store.save<DistributionBucket>(bucket)
  331. }
  332. export async function storage_DistributionBucketStatusUpdated({
  333. event,
  334. store,
  335. }: EventContext & StoreContext): Promise<void> {
  336. const [bucketId, acceptingNewBags] = new Storage.DistributionBucketStatusUpdatedEvent(event).params
  337. const bucket = await getById(store, DistributionBucket, distributionBucketId(bucketId))
  338. bucket.acceptingNewBags = acceptingNewBags.valueOf()
  339. await store.save<DistributionBucket>(bucket)
  340. }
  341. export async function storage_DistributionBucketDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
  342. const [bucketId] = new Storage.DistributionBucketDeletedEvent(event).params
  343. // TODO: Cascade remove on db level (would require changes in Hydra / comitting autogenerated files)
  344. const distributionBucket = await store.get(DistributionBucket, {
  345. where: { id: distributionBucketId(bucketId) },
  346. relations: ['bags', 'bags.distributionBuckets'],
  347. })
  348. if (!distributionBucket) {
  349. inconsistentState(`Distribution bucket by id ${distributionBucketId(bucketId)} not found!`)
  350. }
  351. // Remove relations
  352. await Promise.all(
  353. (distributionBucket.bags || []).map((bag) => {
  354. bag.distributionBuckets = (bag.distributionBuckets || []).filter(
  355. (bucket) => bucket.id !== distributionBucketId(bucketId)
  356. )
  357. return store.save<StorageBag>(bag)
  358. })
  359. )
  360. await store.remove<DistributionBucket>(distributionBucket)
  361. }
  362. export async function storage_DistributionBucketsUpdatedForBag({
  363. event,
  364. store,
  365. }: EventContext & StoreContext): Promise<void> {
  366. const [
  367. bagId,
  368. familyId,
  369. addedBucketsIndices,
  370. removedBucketsIndices,
  371. ] = new Storage.DistributionBucketsUpdatedForBagEvent(event).params
  372. // Get or create bag
  373. const storageBag = await getBag(store, bagId, ['distributionBuckets'])
  374. const removedBucketsIds = Array.from(removedBucketsIndices).map((bucketIndex) =>
  375. distributionBucketIdByFamilyAndIndex(familyId, bucketIndex)
  376. )
  377. const addedBucketsIds = Array.from(addedBucketsIndices).map((bucketIndex) =>
  378. distributionBucketIdByFamilyAndIndex(familyId, bucketIndex)
  379. )
  380. storageBag.distributionBuckets = (storageBag.distributionBuckets || [])
  381. .filter((bucket) => !removedBucketsIds.includes(bucket.id))
  382. .concat(addedBucketsIds.map((id) => new DistributionBucket({ id })))
  383. await store.save<StorageBag>(storageBag)
  384. }
  385. export async function storage_DistributionBucketModeUpdated({
  386. event,
  387. store,
  388. }: EventContext & StoreContext): Promise<void> {
  389. const [bucketId, distributing] = new Storage.DistributionBucketModeUpdatedEvent(event).params
  390. const bucket = await getById(store, DistributionBucket, distributionBucketId(bucketId))
  391. bucket.distributing = distributing.valueOf()
  392. await store.save<DistributionBucket>(bucket)
  393. }
  394. export async function storage_DistributionBucketOperatorInvited({
  395. event,
  396. store,
  397. }: EventContext & StoreContext): Promise<void> {
  398. const [bucketId, workerId] = new Storage.DistributionBucketOperatorInvitedEvent(event).params
  399. const bucket = await getById(store, DistributionBucket, distributionBucketId(bucketId))
  400. const invitedOperator = new DistributionBucketOperator({
  401. id: distributionOperatorId(bucketId, workerId),
  402. distributionBucket: bucket,
  403. status: DistributionBucketOperatorStatus.INVITED,
  404. workerId: workerId.toNumber(),
  405. })
  406. await store.save<DistributionBucketOperator>(invitedOperator)
  407. }
  408. export async function storage_DistributionBucketInvitationCancelled({
  409. event,
  410. store,
  411. }: EventContext & StoreContext): Promise<void> {
  412. const [bucketId, workerId] = new Storage.DistributionBucketOperatorInvitedEvent(event).params
  413. const invitedOperator = await getById(store, DistributionBucketOperator, distributionOperatorId(bucketId, workerId))
  414. await store.remove<DistributionBucketOperator>(invitedOperator)
  415. }
  416. export async function storage_DistributionBucketInvitationAccepted({
  417. event,
  418. store,
  419. }: EventContext & StoreContext): Promise<void> {
  420. const [workerId, bucketId] = new Storage.DistributionBucketInvitationAcceptedEvent(event).params
  421. const invitedOperator = await getById(store, DistributionBucketOperator, distributionOperatorId(bucketId, workerId))
  422. invitedOperator.status = DistributionBucketOperatorStatus.ACTIVE
  423. await store.save<DistributionBucketOperator>(invitedOperator)
  424. }
  425. export async function storage_DistributionBucketMetadataSet({
  426. event,
  427. store,
  428. }: EventContext & StoreContext): Promise<void> {
  429. const [workerId, bucketId, metadataBytes] = new Storage.DistributionBucketMetadataSetEvent(event).params
  430. const operator = await getDistributionBucketOperatorWithMetadata(store, distributionOperatorId(bucketId, workerId))
  431. operator.metadata = await processDistributionOperatorMetadata(event, store, operator.metadata, metadataBytes)
  432. await store.save<DistributionBucketOperator>(operator)
  433. }
  434. export async function storage_DistributionBucketOperatorRemoved({
  435. event,
  436. store,
  437. }: EventContext & StoreContext): Promise<void> {
  438. const [bucketId, workerId] = new Storage.DistributionBucketOperatorRemovedEvent(event).params
  439. // TODO: Cascade remove on db level (would require changes in Hydra / comitting autogenerated files)
  440. const operator = await getDistributionBucketOperatorWithMetadata(store, distributionOperatorId(bucketId, workerId))
  441. await store.remove<DistributionBucketOperator>(operator)
  442. if (operator.metadata) {
  443. await store.remove<DistributionBucketOperatorMetadata>(operator.metadata)
  444. if (operator.metadata.nodeLocation) {
  445. await store.remove<NodeLocationMetadata>(operator.metadata.nodeLocation)
  446. if (operator.metadata.nodeLocation.coordinates) {
  447. await store.remove<GeoCoordinates>(operator.metadata.nodeLocation.coordinates)
  448. }
  449. }
  450. }
  451. }
  452. // STORAGE SYSTEM GLOBAL PARAMS
  453. export async function storage_UpdateBlacklist({ event, store }: EventContext & StoreContext): Promise<void> {
  454. const [removedContentIds, addedContentIds] = new Storage.UpdateBlacklistEvent(event).params
  455. const storageSystem = await getStorageSystem(store)
  456. storageSystem.blacklist = storageSystem.blacklist
  457. .filter((cid) => !Array.from(removedContentIds).some((id) => id.eq(cid)))
  458. .concat(Array.from(addedContentIds).map((id) => id.toString()))
  459. await store.save<StorageSystemParameters>(storageSystem)
  460. }
  461. export async function storage_DistributionBucketsPerBagLimitUpdated({
  462. event,
  463. store,
  464. }: EventContext & StoreContext): Promise<void> {
  465. const [newLimit] = new Storage.DistributionBucketsPerBagLimitUpdatedEvent(event).params
  466. const storageSystem = await getStorageSystem(store)
  467. storageSystem.distributionBucketsPerBagLimit = newLimit.toNumber()
  468. await store.save<StorageSystemParameters>(storageSystem)
  469. }
  470. export async function storage_StorageBucketsPerBagLimitUpdated({
  471. event,
  472. store,
  473. }: EventContext & StoreContext): Promise<void> {
  474. const [newLimit] = new Storage.StorageBucketsPerBagLimitUpdatedEvent(event).params
  475. const storageSystem = await getStorageSystem(store)
  476. storageSystem.storageBucketsPerBagLimit = newLimit.toNumber()
  477. await store.save<StorageSystemParameters>(storageSystem)
  478. }
  479. export async function storage_StorageBucketsVoucherMaxLimitsUpdated({
  480. event,
  481. store,
  482. }: EventContext & StoreContext): Promise<void> {
  483. const [sizeLimit, countLimit] = new Storage.StorageBucketsVoucherMaxLimitsUpdatedEvent(event).params
  484. const storageSystem = await getStorageSystem(store)
  485. storageSystem.storageBucketMaxObjectsSizeLimit = sizeLimit
  486. storageSystem.storageBucketMaxObjectsCountLimit = countLimit
  487. await store.save<StorageSystemParameters>(storageSystem)
  488. }
  489. export async function storage_UploadingBlockStatusUpdated({
  490. event,
  491. store,
  492. }: EventContext & StoreContext): Promise<void> {
  493. const [isBlocked] = new Storage.UploadingBlockStatusUpdatedEvent(event).params
  494. const storageSystem = await getStorageSystem(store)
  495. storageSystem.uploadingBlocked = isBlocked.isTrue
  496. await store.save<StorageSystemParameters>(storageSystem)
  497. }
  498. export async function storage_DataObjectPerMegabyteFeeUpdated({
  499. event,
  500. store,
  501. }: EventContext & StoreContext): Promise<void> {
  502. const [newFee] = new Storage.DataObjectPerMegabyteFeeUpdatedEvent(event).params
  503. const storageSystem = await getStorageSystem(store)
  504. storageSystem.dataObjectFeePerMb = newFee
  505. await store.save<StorageSystemParameters>(storageSystem)
  506. }