content_config.rs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. use codec::Decode;
  2. use node_runtime::{
  3. common::storage::StorageObjectOwner,
  4. data_directory::{DataObject, Quota},
  5. ChannelId, ContentId, DAOId, DataDirectoryConfig, MemberId, Runtime,
  6. };
  7. use serde::Deserialize;
  8. use std::{fs, path::Path};
  9. // Because of the way that the @joystream/types were implemented the getters for
  10. // the string types return a `string` not the `Text` type so when we are serializing
  11. // them to json we get a string rather than an array of bytes, so deserializing them
  12. // is failing. So we are relying on parity codec encoding instead..
  13. #[derive(Decode)]
  14. struct Content {
  15. content_id: ContentId,
  16. data_object: DataObject<Runtime>,
  17. storage_object_owner: StorageObjectOwner<MemberId, ChannelId, DAOId>,
  18. quota: Quota,
  19. }
  20. #[derive(Decode)]
  21. struct ContentData {
  22. /// DataObject(s) and ContentId
  23. data_objects: Vec<Content>,
  24. quota_size_limit_upper_bound: u64,
  25. quota_objects_limit_upper_bound: u64,
  26. global_quota: Quota,
  27. uploading_blocked: bool,
  28. }
  29. #[derive(Deserialize)]
  30. struct EncodedContent {
  31. /// hex encoded ContentId
  32. content_id: String,
  33. /// hex encoded DataObject<Runtime>
  34. data_object: String,
  35. /// hex encoded StorageObjectOwner
  36. storage_object_owner: String,
  37. /// hex encoded Quota
  38. quota: String,
  39. }
  40. impl EncodedContent {
  41. fn decode(&self) -> Content {
  42. // hex string must not include '0x' prefix!
  43. let encoded_content_id = hex::decode(&self.content_id[2..].as_bytes())
  44. .expect("failed to parse content_id hex string");
  45. let encoded_data_object = hex::decode(&self.data_object[2..].as_bytes())
  46. .expect("failed to parse data_object hex string");
  47. let encoded_storage_object_owner = hex::decode(&self.storage_object_owner[2..].as_bytes())
  48. .expect("failed to parse content_id hex string");
  49. let encoded_quota = hex::decode(&self.quota[2..].as_bytes())
  50. .expect("failed to parse data_object hex string");
  51. Content {
  52. content_id: Decode::decode(&mut encoded_content_id.as_slice()).unwrap(),
  53. data_object: Decode::decode(&mut encoded_data_object.as_slice()).unwrap(),
  54. storage_object_owner: Decode::decode(&mut encoded_storage_object_owner.as_slice())
  55. .unwrap(),
  56. quota: Decode::decode(&mut encoded_quota.as_slice()).unwrap(),
  57. }
  58. }
  59. }
  60. #[derive(Deserialize)]
  61. struct EncodedContentData {
  62. /// EncodedContent
  63. data_objects: Vec<EncodedContent>,
  64. /// hex encoded QuotaSizeLimitUpperBound
  65. quota_size_limit_upper_bound: String,
  66. /// hex encoded QuotaObjectsLimitUpperBound
  67. quota_objects_limit_upper_bound: String,
  68. /// hex encoded GlobalQuota
  69. global_quota: String,
  70. /// hex encoded UploadingBlocked flag
  71. uploading_blocked: String,
  72. }
  73. fn parse_content_data(data_file: &Path) -> EncodedContentData {
  74. let data = fs::read_to_string(data_file).expect("Failed reading file");
  75. serde_json::from_str(&data).expect("failed parsing content data")
  76. }
  77. impl EncodedContentData {
  78. pub fn decode(&self) -> ContentData {
  79. ContentData {
  80. data_objects: self
  81. .data_objects
  82. .iter()
  83. .map(|data_objects| data_objects.decode())
  84. .collect(),
  85. quota_size_limit_upper_bound: {
  86. let encoded_quota_size_limit_upper_bound =
  87. hex::decode(&self.quota_size_limit_upper_bound[2..].as_bytes())
  88. .expect("failed to parse data_object hex string");
  89. Decode::decode(&mut encoded_quota_size_limit_upper_bound.as_slice()).unwrap()
  90. },
  91. quota_objects_limit_upper_bound: {
  92. let encoded_quota_objects_limit_upper_bound =
  93. hex::decode(&self.quota_objects_limit_upper_bound[2..].as_bytes())
  94. .expect("failed to parse data_object hex string");
  95. Decode::decode(&mut encoded_quota_objects_limit_upper_bound.as_slice()).unwrap()
  96. },
  97. global_quota: {
  98. let encoded_global_quota = hex::decode(&self.global_quota[2..].as_bytes())
  99. .expect("failed to parse data_object hex string");
  100. Decode::decode(&mut encoded_global_quota.as_slice()).unwrap()
  101. },
  102. uploading_blocked: {
  103. let encoded_uploading_blocked =
  104. hex::decode(&self.uploading_blocked[2..].as_bytes())
  105. .expect("failed to parse data_object hex string");
  106. Decode::decode(&mut encoded_uploading_blocked.as_slice()).unwrap()
  107. },
  108. }
  109. }
  110. }
  111. /// Generates a basic empty `DataDirectoryConfig` genesis config
  112. pub fn empty_data_directory_config() -> DataDirectoryConfig {
  113. DataDirectoryConfig {
  114. data_object_by_content_id: vec![],
  115. known_content_ids: vec![],
  116. quotas: vec![],
  117. quota_size_limit_upper_bound: 20000,
  118. quota_objects_limit_upper_bound: 200,
  119. global_quota: Quota::new(2000000, 2000),
  120. uploading_blocked: false,
  121. }
  122. }
  123. /// Generates a `DataDirectoryConfig` genesis config
  124. /// pre-populated with data objects and known content ids parsed from
  125. /// a json file serialized as a `ContentData` struct
  126. pub fn data_directory_config_from_json(data_file: &Path) -> DataDirectoryConfig {
  127. let content = parse_content_data(data_file).decode();
  128. DataDirectoryConfig {
  129. data_object_by_content_id: content
  130. .data_objects
  131. .iter()
  132. .map(|object| (object.content_id, object.data_object.clone()))
  133. .collect(),
  134. quotas: content
  135. .data_objects
  136. .iter()
  137. .map(|object| (object.storage_object_owner.clone(), object.quota))
  138. .collect(),
  139. known_content_ids: content
  140. .data_objects
  141. .into_iter()
  142. .map(|object| object.content_id)
  143. .collect(),
  144. quota_size_limit_upper_bound: content.quota_size_limit_upper_bound,
  145. quota_objects_limit_upper_bound: content.quota_objects_limit_upper_bound,
  146. global_quota: content.global_quota,
  147. uploading_blocked: content.uploading_blocked,
  148. }
  149. }