Browse Source

Merge branch 'giza' into giza-protobuf-and-query-node

Leszek Wiesner 3 years ago
parent
commit
b38e5e4ff8

+ 4 - 0
runtime-modules/content/src/errors.rs

@@ -76,5 +76,9 @@ decl_error! {
         /// Channel Contains Assets
         ChannelContainsAssets,
 
+        /// Bag Size specified is not valid
+        InvalidBagSizeSpecified,
+
+
     }
 }

+ 165 - 225
runtime-modules/content/src/lib.rs

@@ -100,19 +100,6 @@ pub trait Trait:
     type MaxNumberOfCuratorsPerGroup: Get<MaxNumber>;
 }
 
-/// Specifies how a new asset will be provided on creating and updating
-/// Channels, Videos, Series and Person
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub enum NewAssetsRecord<Balance> {
-    /// Upload to the storage frame_system
-    Upload(CreationUploadParameters<Balance>),
-    /// Multiple url strings pointing at an asset
-    Urls(Vec<AssetUrls>),
-}
-
-type NewAssets<T> = NewAssetsRecord<<T as balances::Trait>::Balance>;
-
 /// The owner of a channel, is the authorized "actor" that can update
 /// or delete or transfer a channel and its contents.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
@@ -179,8 +166,6 @@ pub struct ChannelRecord<MemberId, CuratorGroupId, AccountId> {
     reward_account: Option<AccountId>,
     /// Account for withdrawing deletion prize funds
     deletion_prize_source_account_id: AccountId,
-    /// Number of asset held in storage
-    num_assets: u64,
 }
 
 // Channel alias type for simplification.
@@ -218,32 +203,37 @@ pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRec
 /// Information about channel being created.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub struct ChannelCreationParametersRecord<NewAssets, AccountId> {
+pub struct ChannelCreationParametersRecord<StorageAssets, AccountId> {
     /// Asset collection for the channel, referenced by metadata
-    assets: NewAssets,
+    assets: Option<StorageAssets>,
     /// Metadata about the channel.
-    meta: Vec<u8>,
+    meta: Option<Vec<u8>>,
     /// optional reward account
     reward_account: Option<AccountId>,
 }
 
 type ChannelCreationParameters<T> =
-    ChannelCreationParametersRecord<NewAssets<T>, <T as frame_system::Trait>::AccountId>;
+    ChannelCreationParametersRecord<StorageAssets<T>, <T as frame_system::Trait>::AccountId>;
 
 /// Information about channel being updated.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct ChannelUpdateParametersRecord<NewAssets, AccountId> {
+pub struct ChannelUpdateParametersRecord<StorageAssets, AccountId, DataObjectId: Ord> {
     /// Asset collection for the channel, referenced by metadata    
-    assets: Option<NewAssets>,
+    assets_to_upload: Option<StorageAssets>,
     /// If set, metadata update for the channel.
     new_meta: Option<Vec<u8>>,
     /// If set, updates the reward account of the channel
     reward_account: Option<Option<AccountId>>,
+    /// assets to be removed from channel
+    assets_to_remove: BTreeSet<DataObjectId>,
 }
 
-type ChannelUpdateParameters<T> =
-    ChannelUpdateParametersRecord<NewAssets<T>, <T as frame_system::Trait>::AccountId>;
+type ChannelUpdateParameters<T> = ChannelUpdateParametersRecord<
+    StorageAssets<T>,
+    <T as frame_system::Trait>::AccountId,
+    DataObjectId<T>,
+>;
 
 /// A category that videos can belong to.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
@@ -272,7 +262,7 @@ pub struct VideoCategoryUpdateParameters {
 /// Information regarding the content being uploaded
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub struct CreationUploadParameters<Balance> {
+pub struct StorageAssetsRecord<Balance> {
     /// Data object parameters.
     pub object_creation_list: Vec<DataObjectCreationParameters>,
 
@@ -280,49 +270,47 @@ pub struct CreationUploadParameters<Balance> {
     pub expected_data_size_fee: Balance,
 }
 
+type StorageAssets<T> = StorageAssetsRecord<<T as balances::Trait>::Balance>;
+
 /// Information about the video being created.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub struct VideoCreationParametersRecord<NewAssets> {
+pub struct VideoCreationParametersRecord<StorageAssets> {
     /// Asset collection for the video
-    assets: NewAssets,
+    assets: Option<StorageAssets>,
     /// Metadata for the video.
-    meta: Vec<u8>,
+    meta: Option<Vec<u8>>,
 }
 
-type VideoCreationParameters<T> = VideoCreationParametersRecord<NewAssets<T>>;
+type VideoCreationParameters<T> = VideoCreationParametersRecord<StorageAssets<T>>;
 
 /// Information about the video being updated
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct VideoUpdateParametersRecord<NewAssets> {
+pub struct VideoUpdateParametersRecord<StorageAssets, DataObjectId: Ord> {
     /// Assets referenced by metadata
-    assets: Option<NewAssets>,
+    assets_to_upload: Option<StorageAssets>,
     /// If set, metadata update for the video.
     new_meta: Option<Vec<u8>>,
+    /// video assets to be removed from channel
+    assets_to_remove: BTreeSet<DataObjectId>,
 }
 
-type VideoUpdateParameters<T> = VideoUpdateParametersRecord<NewAssets<T>>;
+type VideoUpdateParameters<T> = VideoUpdateParametersRecord<StorageAssets<T>, DataObjectId<T>>;
 
 /// A video which belongs to a channel. A video may be part of a series or playlist.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct VideoRecord<ChannelId, SeriesId, DataObjectId: Ord> {
+pub struct VideoRecord<ChannelId, SeriesId> {
     pub in_channel: ChannelId,
     // keep track of which season the video is in if it is an 'episode'
     // - prevent removing a video if it is in a season (because order is important)
     pub in_series: Option<SeriesId>,
     /// Whether the curators have censored the video or not.
     pub is_censored: bool,
-    /// storage parameters used during deletion
-    pub maybe_data_objects_id_set: Option<BTreeSet<DataObjectId>>,
 }
 
-type Video<T> = VideoRecord<
-    <T as storage::Trait>::ChannelId,
-    <T as Trait>::SeriesId,
-    <T as storage::Trait>::DataObjectId,
->;
+type Video<T> = VideoRecord<<T as storage::Trait>::ChannelId, <T as Trait>::SeriesId>;
 
 /// Information about the plyalist being created.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
@@ -352,9 +340,9 @@ pub struct Playlist<ChannelId> {
 /// Information about the episode being created or updated.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub enum EpisodeParameters<VideoId, NewAssets> {
+pub enum EpisodeParameters<VideoId, StorageAssets> {
     /// A new video is being added as the episode.
-    NewVideo(VideoCreationParametersRecord<NewAssets>),
+    NewVideo(VideoCreationParametersRecord<StorageAssets>),
     /// An existing video is being made into an episode.
     ExistingVideo(VideoId),
 }
@@ -362,15 +350,15 @@ pub enum EpisodeParameters<VideoId, NewAssets> {
 /// Information about the season being created or updated.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct SeasonParameters<VideoId, NewAssets> {
+pub struct SeasonParameters<VideoId, StorageAssets> {
     /// Season assets referenced by metadata
-    assets: Option<NewAssets>,
+    assets: Option<StorageAssets>,
     // ?? It might just be more straighforward to always provide full list of episodes at cost of larger tx.
     /// If set, updates the episodes of a season. Extends the number of episodes in a season
     /// when length of new_episodes is greater than previously set. Last elements must all be
     /// 'Some' in that case.
     /// Will truncate existing season when length of new_episodes is less than previously set.
-    episodes: Option<Vec<Option<EpisodeParameters<VideoId, NewAssets>>>>,
+    episodes: Option<Vec<Option<EpisodeParameters<VideoId, StorageAssets>>>>,
 
     meta: Option<Vec<u8>>,
 }
@@ -378,14 +366,14 @@ pub struct SeasonParameters<VideoId, NewAssets> {
 /// Information about the series being created or updated.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct SeriesParameters<VideoId, NewAssets> {
+pub struct SeriesParameters<VideoId, StorageAssets> {
     /// Series assets referenced by metadata
-    assets: Option<NewAssets>,
+    assets: Option<StorageAssets>,
     // ?? It might just be more straighforward to always provide full list of seasons at cost of larger tx.
     /// If set, updates the seasons of a series. Extend a series when length of seasons is
     /// greater than previoulsy set. Last elements must all be 'Some' in that case.
     /// Will truncate existing series when length of seasons is less than previously set.
-    seasons: Option<Vec<Option<SeasonParameters<VideoId, NewAssets>>>>,
+    seasons: Option<Vec<Option<SeasonParameters<VideoId, StorageAssets>>>>,
     meta: Option<Vec<u8>>,
 }
 
@@ -433,9 +421,9 @@ impl<MemberId: Default> Default for PersonController<MemberId> {
 /// Information for Person being created.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub struct PersonCreationParameters<NewAssets> {
+pub struct PersonCreationParameters<StorageAssets> {
     /// Assets referenced by metadata
-    assets: NewAssets,
+    assets: StorageAssets,
     /// Metadata for person.
     meta: Vec<u8>,
 }
@@ -443,9 +431,9 @@ pub struct PersonCreationParameters<NewAssets> {
 /// Information for Persion being updated.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct PersonUpdateParameters<NewAssets> {
+pub struct PersonUpdateParameters<StorageAssets> {
     /// Assets referenced by metadata
-    assets: Option<NewAssets>,
+    assets: Option<StorageAssets>,
     /// Metadata to update person.
     new_meta: Option<Vec<u8>>,
 }
@@ -458,6 +446,8 @@ pub struct Person<MemberId> {
     controlled_by: PersonController<MemberId>,
 }
 
+type DataObjectId<T> = <T as storage::Trait>::DataObjectId;
+
 decl_storage! {
     trait Store for Module<T: Trait> as Content {
         pub ChannelById get(fn channel_by_id): map hasher(blake2_128_concat) T::ChannelId => Channel<T>;
@@ -651,27 +641,17 @@ decl_module! {
             // The channel owner will be..
             let channel_owner = Self::actor_to_channel_owner(&actor)?;
 
-
             // next channel id
             let channel_id = NextChannelId::<T>::get();
 
-            // get uploading parameters if assets have to be saved on storage
-            let maybe_upload_parameters = Self::pick_upload_parameters_from_assets(
-                &params.assets,
-                &channel_id,
-                &sender,
-            );
-
-            // number of assets succesfully uploaded
-            let num_assets = maybe_upload_parameters
-                .map_or(Ok(0u64), |upload_parameters| {
-                Storage::<T>::upload_data_objects(upload_parameters.clone())
-                    .map(|_| {
-                        upload_parameters
-                        .object_creation_list
-                        .len() as u64
-                })
-            })?;
+            // atomically upload to storage and return the # of uploaded assets
+            if let Some(upload_assets) = params.assets.as_ref() {
+                Self::upload_assets_to_storage(
+                    upload_assets,
+                    &channel_id,
+                    &sender,
+                )?;
+            }
 
             //
             // == MUTATION SAFE ==
@@ -687,8 +667,6 @@ decl_module! {
                 num_videos: 0u64,
                 is_censored: false,
                 reward_account: params.reward_account.clone(),
-                // number of assets uploaded
-                num_assets,
                 // setting the channel owner account as the prize funds account
                 deletion_prize_source_account_id: sender,
             };
@@ -707,8 +685,6 @@ decl_module! {
             channel_id: T::ChannelId,
             params: ChannelUpdateParameters<T>,
         ) {
-            let sender = ensure_signed(origin.clone())?;
-
             // check that channel exists
             let channel = Self::ensure_channel_exists(&channel_id)?;
 
@@ -718,23 +694,17 @@ decl_module! {
                 &channel.owner,
             )?;
 
-            let maybe_upload_parameters = params.assets.clone()
-                .and_then(|assets| {Self::pick_upload_parameters_from_assets(
-                   &assets,
+            Self::remove_assets_from_storage(&params.assets_to_remove, &channel_id, &channel.deletion_prize_source_account_id)?;
+
+            // atomically upload to storage and return the # of uploaded assets
+            if let Some(upload_assets) = params.assets_to_upload.as_ref() {
+                Self::upload_assets_to_storage(
+                    upload_assets,
                     &channel_id,
-            &sender,
-            )});
-
-            // number of assets succesfully uploaded
-            let maybe_num_assets = maybe_upload_parameters.as_ref()
-                    .map_or(
-                        Ok(Some(0u64)),
-                        |upload_parameters| {
-                        Storage::<T>::upload_data_objects(upload_parameters.clone())
-                     .map(|_| {
-                        Some(upload_parameters.object_creation_list.len() as u64)
-             })
-            })?;
+                    &channel.deletion_prize_source_account_id
+                )?;
+            }
+
             //
             // == MUTATION SAFE ==
             //
@@ -746,23 +716,19 @@ decl_module! {
                 channel.reward_account = reward_account.clone();
             }
 
-            // Maybe update asset num
-            if let Some(num_assets) = maybe_num_assets {
-                channel.num_assets = channel.num_assets.saturating_add(num_assets);
-            }
-
             // Update the channel
             ChannelById::<T>::insert(channel_id, channel.clone());
 
             Self::deposit_event(RawEvent::ChannelUpdated(actor, channel_id, channel, params));
         }
 
-            // extrinsics for channel deletion
+        // extrinsics for channel deletion
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn delete_channel(
             origin,
             actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             channel_id: T::ChannelId,
+            num_objects_to_delete: u64,
         ) -> DispatchResult {
             // check that channel exists
             let channel = Self::ensure_channel_exists(&channel_id)?;
@@ -774,74 +740,47 @@ decl_module! {
                 &channel.owner,
             )?;
 
-            // check that channel assets are 0
-            ensure!(channel.num_assets == 0, Error::<T>::ChannelContainsAssets);
-
             // check that channel videos are 0
             ensure!(channel.num_videos == 0, Error::<T>::ChannelContainsVideos);
 
-            // delete channel dynamic bag
+            // get bag id for the channel
             let dyn_bag = DynamicBagIdType::<T::MemberId, T::ChannelId>::Channel(channel_id);
-            Storage::<T>::delete_dynamic_bag(
-                channel.deletion_prize_source_account_id,
-                dyn_bag
-            )?;
-
-            // remove channel from on chain state
-            ChannelById::<T>::remove(channel_id);
+            let bag_id = storage::BagIdType::from(dyn_bag.clone());
 
-            // deposit event
-            Self::deposit_event(RawEvent::ChannelDeleted(actor, channel_id));
-
-            Ok(())
-        }
+            // ensure that bag size provided is valid
+            ensure!(
+                storage::Bags::<T>::get(&bag_id).objects_number == num_objects_to_delete,
+                Error::<T>::InvalidBagSizeSpecified
+            );
 
-        /// Remove assets of a channel from storage
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn remove_channel_assets(
-            origin,
-            actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            channel_id: T::ChannelId,
-            assets: BTreeSet<<T as storage::Trait>::DataObjectId>,
-        ) {
-            // check that channel exists
-            let channel = Self::ensure_channel_exists(&channel_id)?;
+            // construct collection of assets to be removed
+            let assets_to_remove: BTreeSet<DataObjectId<T>> =
+                storage::DataObjectsById::<T>::iter_prefix(&bag_id).map(|x| x.0).collect();
 
-            ensure_actor_authorized_to_update_channel::<T>(
-                origin,
-                &actor,
-                &channel.owner,
+            // remove specified assets from storage
+            Self::remove_assets_from_storage(
+                &assets_to_remove,
+                &channel_id,
+                &channel.deletion_prize_source_account_id
             )?;
 
-            // ensure that the provided assets are not empty
-            ensure!(!assets.is_empty(), Error::<T>::NoAssetsSpecified);
-
-            let num_assets_to_remove = assets.len() as u64;
-
-            // cannot remove more asset than those already present
-            ensure!(
-                num_assets_to_remove <= channel.num_assets,
-                Error::<T>::InvalidAssetsProvided
-            );
-
-            // remove assets from storage
-            Storage::<T>::delete_data_objects(
-                channel.deletion_prize_source_account_id.clone(),
-                Self::bag_id_for_channel(&channel_id),
-                assets.clone(),
+            // delete channel dynamic bag
+            Storage::<T>::delete_dynamic_bag(
+                channel.deletion_prize_source_account_id,
+                dyn_bag
             )?;
 
             //
             // == MUTATION SAFE ==
             //
 
-            // update onchain channel status
-            let mut channel = channel;
-            channel.num_assets = channel.num_assets.saturating_sub(num_assets_to_remove);
-            ChannelById::<T>::insert(channel_id, channel.clone());
+            // remove channel from on chain state
+            ChannelById::<T>::remove(channel_id);
 
+            // deposit event
+            Self::deposit_event(RawEvent::ChannelDeleted(actor, channel_id));
 
-            Self::deposit_event(RawEvent::ChannelAssetsRemoved(actor, channel_id, assets, channel));
+            Ok(())
         }
 
         #[weight = 10_000_000] // TODO: adjust weight
@@ -974,8 +913,6 @@ decl_module! {
             params: VideoCreationParameters<T>,
         ) {
 
-            let sender = ensure_signed(origin.clone())?;
-
             // check that channel exists
             let channel = Self::ensure_channel_exists(&channel_id)?;
 
@@ -988,26 +925,14 @@ decl_module! {
             // next video id
             let video_id = NextVideoId::<T>::get();
 
-            // adding the content to storage node if uploading is needed
-            let maybe_upload_parameters = Self::pick_upload_parameters_from_assets(
-                &params.assets,
-                &channel_id,
-        &sender,
-            );
-
-            // if storaged uploading is required save t he object id for the video
-            let maybe_data_objects_ids = maybe_upload_parameters
-                .map_or(
-                    Ok(None),
-                    |upload_parameters| {
-                     // beginning object id
-                        let beg = Storage::<T>::next_data_object_id();
-
-                        // upload objects and return their indexes
-                        Storage::<T>::upload_data_objects(upload_parameters)
-                        .map(|_| Storage::<T>::next_data_object_id()) // ending index
-                        .map(|end| Some((beg..end).collect::<BTreeSet<_>>())) // create collection
-                })?;
+            // atomically upload to storage and return the # of uploaded assets
+            if let Some(upload_assets) = params.assets.as_ref() {
+                Self::upload_assets_to_storage(
+                    upload_assets,
+                    &channel_id,
+                    &channel.deletion_prize_source_account_id
+                )?;
+            }
 
             //
             // == MUTATION SAFE ==
@@ -1021,8 +946,6 @@ decl_module! {
                 in_series: None,
                 /// Whether the curators have censored the video or not.
                 is_censored: false,
-                /// storage parameters for later storage deletion
-                maybe_data_objects_id_set: maybe_data_objects_ids,
             };
 
             // add it to the onchain state
@@ -1047,40 +970,34 @@ decl_module! {
             video_id: T::VideoId,
             params: VideoUpdateParameters<T>,
         ) {
-            let sender = ensure_signed(origin.clone())?;
-
             // check that video exists, retrieve corresponding channel id.
-            let channel_id = Self::ensure_video_exists(&video_id)?.in_channel;
+            let video = Self::ensure_video_exists(&video_id)?;
+
+            let channel_id = video.in_channel;
+            let channel = ChannelById::<T>::get(&channel_id);
 
             ensure_actor_authorized_to_update_channel::<T>(
                 origin,
                 &actor,
-                &Self::channel_by_id(channel_id).owner,
+                &channel.owner,
             )?;
 
-            // Pick the assets to be uploaded to storage frame_system out
-            if let Some(assets) = &params.assets {
-                // adding content to storage if needed
-               let maybe_upload_parameters = Self::pick_upload_parameters_from_assets(
-                   assets,
-                   &channel_id,
-                   &sender,
-               );
-
-              if let Some(upload_parameters) = maybe_upload_parameters{
-                 Storage::<T>::upload_data_objects(upload_parameters)?;
-              }
+            // remove specified assets from channel bag in storage
+            Self::remove_assets_from_storage(&params.assets_to_remove, &channel_id, &channel.deletion_prize_source_account_id)?;
+
+            // atomically upload to storage and return the # of uploaded assets
+            if let Some(upload_assets) = params.assets_to_upload.as_ref() {
+                Self::upload_assets_to_storage(
+                    upload_assets,
+                    &channel_id,
+                    &channel.deletion_prize_source_account_id
+                )?;
             }
 
             //
             // == MUTATION SAFE ==
             //
 
-            // increase the number of video the selected channel by 1
-            ChannelById::<T>::mutate(channel_id, |channel| {
-                channel.num_videos = channel.num_videos.saturating_add(1);
-            });
-
             Self::deposit_event(RawEvent::VideoUpdated(actor, video_id, params));
         }
 
@@ -1089,6 +1006,7 @@ decl_module! {
             origin,
             actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             video_id: T::VideoId,
+            assets_to_remove: BTreeSet<DataObjectId<T>>,
         ) {
 
             // check that video exists
@@ -1106,16 +1024,11 @@ decl_module! {
                 &channel.owner,
             )?;
 
+            // ensure video can be removed
             Self::ensure_video_can_be_removed(&video)?;
 
-            // If video is on storage, remove it
-            if let Some(data_objects_id_set) = video.maybe_data_objects_id_set {
-                Storage::<T>::delete_data_objects(
-                    channel.deletion_prize_source_account_id,
-                    Self::bag_id_for_channel(&channel_id),
-                    data_objects_id_set,
-                )?;
-            }
+            // remove specified assets from channel bag in storage
+            Self::remove_assets_from_storage(&assets_to_remove, &channel_id, &channel.deletion_prize_source_account_id)?;
 
             //
             // == MUTATION SAFE ==
@@ -1244,7 +1157,7 @@ decl_module! {
         pub fn create_person(
             _origin,
             _actor: PersonActor<T::MemberId, T::CuratorId>,
-            _params: PersonCreationParameters<NewAssets<T>>,
+            _params: PersonCreationParameters<StorageAssets<T>>,
         ) {
             Self::not_implemented()?;
         }
@@ -1254,7 +1167,7 @@ decl_module! {
             _origin,
             _actor: PersonActor<T::MemberId, T::CuratorId>,
             _person: T::PersonId,
-            _params: PersonUpdateParameters<NewAssets<T>>,
+            _params: PersonUpdateParameters<StorageAssets<T>>,
         ) {
             Self::not_implemented()?;
         }
@@ -1326,7 +1239,7 @@ decl_module! {
             _origin,
             _actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             _channel_id: T::ChannelId,
-            _params: SeriesParameters<T::VideoId, NewAssets<T>>
+            _params: SeriesParameters<T::VideoId, StorageAssets<T>>
         ) {
             Self::not_implemented()?;
         }
@@ -1336,7 +1249,7 @@ decl_module! {
             _origin,
             _actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             _channel_id: T::ChannelId,
-            _params: SeriesParameters<T::VideoId, NewAssets<T>>
+            _params: SeriesParameters<T::VideoId, StorageAssets<T>>
         ) {
             Self::not_implemented()?;
         }
@@ -1415,10 +1328,10 @@ impl<T: Trait> Module<T> {
     }
 
     fn pick_upload_parameters_from_assets(
-        assets: &NewAssets<T>,
+        assets: &StorageAssets<T>,
         channel_id: &T::ChannelId,
-        sender: &T::AccountId,
-    ) -> Option<UploadParameters<T>> {
+        prize_source_account: &T::AccountId,
+    ) -> UploadParameters<T> {
         // dynamic bag for a media object
         let dyn_bag = DynamicBagIdType::<T::MemberId, T::ChannelId>::Channel(*channel_id);
         let bag_id = BagIdType::from(dyn_bag.clone());
@@ -1428,15 +1341,11 @@ impl<T: Trait> Module<T> {
             Storage::<T>::create_dynamic_bag(dyn_bag, None).unwrap();
         }
 
-        if let NewAssets::<T>::Upload(creation_upload_params) = assets {
-            Some(UploadParametersRecord {
-                bag_id,
-                object_creation_list: creation_upload_params.object_creation_list.clone(),
-                deletion_prize_source_account_id: sender.clone(),
-                expected_data_size_fee: creation_upload_params.expected_data_size_fee,
-            })
-        } else {
-            None
+        UploadParametersRecord {
+            bag_id,
+            object_creation_list: assets.object_creation_list.clone(),
+            deletion_prize_source_account_id: prize_source_account.clone(),
+            expected_data_size_fee: assets.expected_data_size_fee,
         }
     }
 
@@ -1462,6 +1371,37 @@ impl<T: Trait> Module<T> {
     fn not_implemented() -> DispatchResult {
         Err(Error::<T>::FeatureNotImplemented.into())
     }
+
+    fn upload_assets_to_storage(
+        assets: &StorageAssets<T>,
+        channel_id: &T::ChannelId,
+        prize_source_account: &T::AccountId,
+    ) -> DispatchResult {
+        // construct upload params
+        let upload_params =
+            Self::pick_upload_parameters_from_assets(assets, channel_id, prize_source_account);
+
+        // attempt to upload objects att
+        Storage::<T>::upload_data_objects(upload_params.clone())?;
+
+        Ok(())
+    }
+
+    fn remove_assets_from_storage(
+        assets: &BTreeSet<DataObjectId<T>>,
+        channel_id: &T::ChannelId,
+        prize_source_account: &T::AccountId,
+    ) -> DispatchResult {
+        // remove assets if any
+        if !assets.is_empty() {
+            Storage::<T>::delete_data_objects(
+                prize_source_account.clone(),
+                Self::bag_id_for_channel(&channel_id),
+                assets.clone(),
+            )?;
+        }
+        Ok(())
+    }
 }
 
 decl_event!(
@@ -1485,13 +1425,13 @@ decl_event!(
         ChannelOwnershipTransferRequest = ChannelOwnershipTransferRequest<T>,
         Series = Series<<T as storage::Trait>::ChannelId, <T as Trait>::VideoId>,
         Channel = Channel<T>,
-        DataObjectId = <T as storage::Trait>::DataObjectId,
+        DataObjectId = DataObjectId<T>,
         IsCensored = bool,
         ChannelCreationParameters = ChannelCreationParameters<T>,
         ChannelUpdateParameters = ChannelUpdateParameters<T>,
         VideoCreationParameters = VideoCreationParameters<T>,
         VideoUpdateParameters = VideoUpdateParameters<T>,
-        NewAssets = NewAssets<T>,
+        StorageAssets = StorageAssets<T>,
     {
         // Curators
         CuratorGroupCreated(CuratorGroupId),
@@ -1565,15 +1505,15 @@ decl_event!(
         SeriesCreated(
             ContentActor,
             SeriesId,
-            NewAssets,
-            SeriesParameters<VideoId, NewAssets>,
+            StorageAssets,
+            SeriesParameters<VideoId, StorageAssets>,
             Series,
         ),
         SeriesUpdated(
             ContentActor,
             SeriesId,
-            NewAssets,
-            SeriesParameters<VideoId, NewAssets>,
+            StorageAssets,
+            SeriesParameters<VideoId, StorageAssets>,
             Series,
         ),
         SeriesDeleted(ContentActor, SeriesId),
@@ -1582,14 +1522,14 @@ decl_event!(
         PersonCreated(
             ContentActor,
             PersonId,
-            NewAssets,
-            PersonCreationParameters<NewAssets>,
+            StorageAssets,
+            PersonCreationParameters<StorageAssets>,
         ),
         PersonUpdated(
             ContentActor,
             PersonId,
-            NewAssets,
-            PersonUpdateParameters<NewAssets>,
+            StorageAssets,
+            PersonUpdateParameters<StorageAssets>,
         ),
         PersonDeleted(ContentActor, PersonId),
         ChannelDeleted(ContentActor, ChannelId),

+ 90 - 89
runtime-modules/content/src/tests/channels.rs

@@ -18,8 +18,8 @@ fn successful_channel_deletion() {
             <Test as balances::Trait>::Balance::from(100u32),
         );
 
-        // 3 assets
-        let assets = NewAssets::<Test>::Upload(CreationUploadParameters {
+        // 3 assets added at creation
+        let assets = StorageAssetsRecord {
             object_creation_list: vec![
                 DataObjectCreationParameters {
                     size: 3,
@@ -35,8 +35,7 @@ fn successful_channel_deletion() {
                 },
             ],
             expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        });
-
+        };
         let channel_id = NextChannelId::<Test>::get();
 
         // create channel
@@ -44,41 +43,29 @@ fn successful_channel_deletion() {
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: assets,
-                meta: vec![],
+                assets: Some(assets),
+                meta: None,
                 reward_account: None,
             },
             Ok(()),
         );
 
-        // attempt to delete channel with non zero assets
+        // attempt to delete channel with non zero assets should result in error: objects
+        // are misspecified
         delete_channel_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
-            Err(Error::<Test>::ChannelContainsAssets.into()),
-        );
-
-        // delete assets
-        let assets_to_delete = [0u64, 1u64, 2u64]
-            .iter()
-            .map(|&x| x)
-            .collect::<BTreeSet<_>>();
-
-        // delete channel assets
-        delete_channel_assets_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            assets_to_delete,
-            Ok(()),
+            2u64,
+            Err(Error::<Test>::InvalidBagSizeSpecified.into()),
         );
 
-        // successful deletion
+        // successful deletion because we empty the bag first
         delete_channel_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
+            3u64,
             Ok(()),
         );
     })
@@ -97,7 +84,7 @@ fn successful_channel_assets_deletion() {
         );
 
         // 3 assets
-        let assets = NewAssets::<Test>::Upload(CreationUploadParameters {
+        let assets = StorageAssetsRecord {
             object_creation_list: vec![
                 DataObjectCreationParameters {
                     size: 3,
@@ -113,7 +100,7 @@ fn successful_channel_assets_deletion() {
                 },
             ],
             expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        });
+        };
 
         let channel_id = NextChannelId::<Test>::get();
         // create channel
@@ -121,24 +108,28 @@ fn successful_channel_assets_deletion() {
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: assets,
-                meta: vec![],
+                assets: Some(assets),
+                meta: Some(vec![]),
                 reward_account: None,
             },
             Ok(()),
         );
 
         // delete assets
-        let assets_to_delete = [0u64, 1u64].iter().map(|&x| x).collect::<BTreeSet<_>>();
+        let assets_to_remove = [0u64, 1u64].iter().map(|&x| x).collect::<BTreeSet<_>>();
 
         // delete channel assets
-        delete_channel_assets_mock(
-            FIRST_MEMBER_ORIGIN,
+        assert_ok!(Content::update_channel(
+            Origin::signed(FIRST_MEMBER_ORIGIN),
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
-            assets_to_delete,
-            Ok(()),
-        );
+            ChannelUpdateParametersRecord {
+                assets_to_upload: None,
+                new_meta: None,
+                reward_account: None,
+                assets_to_remove: assets_to_remove,
+            },
+        ));
     })
 }
 
@@ -155,7 +146,8 @@ fn succesful_channel_update() {
         );
 
         // 2 + 1 assets to be uploaded
-        let assets = NewAssets::<Test>::Upload(CreationUploadParameters {
+        let first_obj_id = Storage::<Test>::next_data_object_id();
+        let first_batch = StorageAssetsRecord {
             object_creation_list: vec![
                 DataObjectCreationParameters {
                     size: 3,
@@ -167,9 +159,11 @@ fn succesful_channel_update() {
                 },
             ],
             expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        });
+        };
+        let first_batch_ids =
+            (first_obj_id..Storage::<Test>::next_data_object_id()).collect::<BTreeSet<_>>();
 
-        let new_assets = NewAssets::<Test>::Upload(CreationUploadParameters {
+        let second_batch = StorageAssetsRecord {
             object_creation_list: vec![
                 DataObjectCreationParameters {
                     size: 3,
@@ -181,43 +175,46 @@ fn succesful_channel_update() {
                 },
             ],
             expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        });
+        };
 
         let channel_id = NextChannelId::<Test>::get();
-        // create channel
+
+        // create channel with first batch of assets
         create_channel_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: assets,
-                meta: vec![],
+                assets: Some(first_batch),
+                meta: Some(vec![]),
                 reward_account: None,
             },
             Ok(()),
         );
 
-        // update channel
+        // update channel by adding the second batch of assets
         update_channel_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
             ChannelUpdateParametersRecord {
-                assets: Some(new_assets),
-                new_meta: None,
+                assets_to_upload: Some(second_batch),
+                new_meta: Some(vec![]),
                 reward_account: None,
+                assets_to_remove: BTreeSet::new(),
             },
             Ok(()),
         );
 
-        // update with 0 assets
+        // update channel by removing the first batch of assets
         update_channel_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
             ChannelUpdateParametersRecord {
-                assets: None,
+                assets_to_upload: None,
                 new_meta: None,
                 reward_account: None,
+                assets_to_remove: first_batch_ids,
             },
             Ok(()),
         );
@@ -237,7 +234,7 @@ fn succesful_channel_creation() {
         );
 
         // 3 assets to be uploaded
-        let assets = NewAssets::<Test>::Upload(CreationUploadParameters {
+        let assets = StorageAssetsRecord {
             object_creation_list: vec![
                 DataObjectCreationParameters {
                     size: 3,
@@ -253,15 +250,15 @@ fn succesful_channel_creation() {
                 },
             ],
             expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        });
+        };
 
         // create channel
         create_channel_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: assets,
-                meta: vec![],
+                assets: Some(assets),
+                meta: Some(vec![]),
                 reward_account: None,
             },
             Ok(()),
@@ -277,8 +274,8 @@ fn lead_cannot_create_channel() {
                 Origin::signed(LEAD_ORIGIN),
                 ContentActor::Lead,
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ),
@@ -299,8 +296,8 @@ fn curator_owned_channels() {
                 Origin::signed(FIRST_CURATOR_ORIGIN),
                 ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ),
@@ -316,8 +313,8 @@ fn curator_owned_channels() {
                 Origin::signed(SECOND_CURATOR_ORIGIN),
                 ContentActor::Curator(FIRST_CURATOR_GROUP_ID, SECOND_CURATOR_ID),
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ),
@@ -330,8 +327,8 @@ fn curator_owned_channels() {
                 Origin::signed(SECOND_CURATOR_ORIGIN),
                 ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ),
@@ -345,8 +342,8 @@ fn curator_owned_channels() {
             Origin::signed(FIRST_CURATOR_ORIGIN),
             ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             }
         ));
@@ -361,12 +358,11 @@ fn curator_owned_channels() {
                     is_censored: false,
                     reward_account: None,
                     deletion_prize_source_account_id: FIRST_CURATOR_ORIGIN,
-                    num_assets: 0,
                     num_videos: 0,
                 },
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ))
@@ -378,10 +374,11 @@ fn curator_owned_channels() {
             ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
             channel_id,
             ChannelUpdateParametersRecord {
-                assets: None,
+                assets_to_upload: None,
                 new_meta: None,
                 reward_account: None,
-            }
+                assets_to_remove: BTreeSet::new(),
+            },
         ));
 
         // Lead can update curator owned channels
@@ -390,10 +387,11 @@ fn curator_owned_channels() {
             ContentActor::Lead,
             channel_id,
             ChannelUpdateParametersRecord {
-                assets: None,
+                assets_to_upload: None,
                 new_meta: None,
                 reward_account: None,
-            }
+                assets_to_remove: BTreeSet::new(),
+            },
         ));
     })
 }
@@ -410,8 +408,8 @@ fn member_owned_channels() {
                 Origin::signed(UNKNOWN_ORIGIN),
                 ContentActor::Member(MEMBERS_COUNT + 1),
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ),
@@ -425,8 +423,8 @@ fn member_owned_channels() {
             Origin::signed(FIRST_MEMBER_ORIGIN),
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             }
         ));
@@ -441,12 +439,12 @@ fn member_owned_channels() {
                     is_censored: false,
                     reward_account: None,
                     deletion_prize_source_account_id: FIRST_MEMBER_ORIGIN,
-                    num_assets: 0,
+
                     num_videos: 0,
                 },
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ))
@@ -459,8 +457,8 @@ fn member_owned_channels() {
             Origin::signed(SECOND_MEMBER_ORIGIN),
             ContentActor::Member(SECOND_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             }
         ));
@@ -475,12 +473,12 @@ fn member_owned_channels() {
                     is_censored: false,
                     reward_account: None,
                     deletion_prize_source_account_id: SECOND_MEMBER_ORIGIN,
-                    num_assets: 0,
+
                     num_videos: 0,
                 },
                 ChannelCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: Some(vec![]),
                     reward_account: None,
                 }
             ))
@@ -492,10 +490,11 @@ fn member_owned_channels() {
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id_1,
             ChannelUpdateParametersRecord {
-                assets: None,
+                assets_to_upload: None,
                 new_meta: None,
                 reward_account: None,
-            }
+                assets_to_remove: BTreeSet::new(),
+            },
         ));
 
         assert_eq!(
@@ -508,13 +507,14 @@ fn member_owned_channels() {
                     is_censored: false,
                     reward_account: None,
                     deletion_prize_source_account_id: FIRST_MEMBER_ORIGIN,
-                    num_assets: 0,
+
                     num_videos: 0,
                 },
                 ChannelUpdateParametersRecord {
-                    assets: None,
+                    assets_to_upload: None,
                     new_meta: None,
                     reward_account: None,
+                    assets_to_remove: BTreeSet::new(),
                 }
             ))
         );
@@ -526,10 +526,11 @@ fn member_owned_channels() {
                 ContentActor::Member(FIRST_MEMBER_ID),
                 channel_id_2,
                 ChannelUpdateParametersRecord {
-                    assets: None,
+                    assets_to_upload: None,
                     new_meta: None,
                     reward_account: None,
-                }
+                    assets_to_remove: BTreeSet::new(),
+                },
             ),
             Error::<Test>::ActorNotAuthorized
         );
@@ -547,8 +548,8 @@ fn channel_censoring() {
             Origin::signed(FIRST_MEMBER_ORIGIN),
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             }
         ));
@@ -623,8 +624,8 @@ fn channel_censoring() {
             Origin::signed(FIRST_CURATOR_ORIGIN),
             ContentActor::Curator(group_id, FIRST_CURATOR_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             }
         ));

+ 6 - 50
runtime-modules/content/src/tests/mock.rs

@@ -445,10 +445,6 @@ pub fn create_channel_mock(
     );
 
     if result.is_ok() {
-        let num_assets = match params.assets.clone() {
-            NewAssets::<Test>::Urls(v) => v.len() as u64,
-            NewAssets::<Test>::Upload(c) => c.object_creation_list.len() as u64,
-        };
         let owner = Content::actor_to_channel_owner(&actor).unwrap();
 
         assert_eq!(
@@ -461,7 +457,6 @@ pub fn create_channel_mock(
                     is_censored: false,
                     reward_account: params.reward_account,
                     deletion_prize_source_account_id: sender,
-                    num_assets: num_assets,
                     num_videos: 0,
                 },
                 params.clone(),
@@ -484,16 +479,12 @@ pub fn update_channel_mock(
             Origin::signed(sender),
             actor.clone(),
             channel_id.clone(),
-            params.clone()
+            params.clone(),
         ),
         result.clone(),
     );
 
     if result.is_ok() {
-        let maybe_num_assets = params.assets.clone().map_or(None, |assets| match assets {
-            NewAssets::<Test>::Urls(v) => Some(v.len() as u64),
-            NewAssets::<Test>::Upload(c) => Some(c.object_creation_list.len() as u64),
-        });
         assert_eq!(
             System::events().last().unwrap().event,
             MetaEvent::content(RawEvent::ChannelUpdated(
@@ -504,7 +495,6 @@ pub fn update_channel_mock(
                     is_censored: channel_pre.is_censored,
                     reward_account: channel_pre.reward_account.clone(),
                     deletion_prize_source_account_id: sender,
-                    num_assets: channel_pre.num_assets + maybe_num_assets.unwrap_or(0),
                     num_videos: channel_pre.num_videos,
                 },
                 params.clone(),
@@ -513,57 +503,23 @@ pub fn update_channel_mock(
     }
 }
 
-pub fn delete_channel_assets_mock(
+pub fn delete_channel_mock(
     sender: u64,
     actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
     channel_id: ChannelId,
-    assets: BTreeSet<<Test as storage::Trait>::DataObjectId>,
+    objects_num: u64,
     result: DispatchResult,
 ) {
-    let channel_pre = ChannelById::<Test>::get(channel_id.clone());
-
     assert_eq!(
-        Content::remove_channel_assets(
+        Content::delete_channel(
             Origin::signed(sender),
             actor.clone(),
             channel_id.clone(),
-            assets.clone(),
+            objects_num,
         ),
         result.clone(),
     );
 
-    if result.is_ok() {
-        let num_assets_removed = assets.len();
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelAssetsRemoved(
-                actor.clone(),
-                channel_id,
-                assets.clone(),
-                ChannelRecord {
-                    owner: channel_pre.owner.clone(),
-                    is_censored: channel_pre.is_censored,
-                    reward_account: channel_pre.reward_account.clone(),
-                    deletion_prize_source_account_id: sender,
-                    num_assets: channel_pre.num_assets - (num_assets_removed as u64),
-                    num_videos: channel_pre.num_videos,
-                },
-            ))
-        );
-    }
-}
-
-pub fn delete_channel_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    channel_id: ChannelId,
-    result: DispatchResult,
-) {
-    assert_eq!(
-        Content::delete_channel(Origin::signed(sender), actor.clone(), channel_id.clone()),
-        result.clone(),
-    );
-
     if result.is_ok() {
         assert_eq!(
             System::events().last().unwrap().event,
@@ -623,7 +579,7 @@ pub fn update_video_mock(
             Origin::signed(sender),
             actor.clone(),
             video_id.clone(),
-            params.clone()
+            params.clone(),
         ),
         result.clone(),
     );

+ 54 - 33
runtime-modules/content/src/tests/videos.rs

@@ -14,8 +14,8 @@ fn create_member_channel() -> ChannelId {
         Origin::signed(FIRST_MEMBER_ORIGIN),
         ContentActor::Member(FIRST_MEMBER_ID),
         ChannelCreationParametersRecord {
-            assets: NewAssets::<Test>::Urls(vec![]),
-            meta: vec![],
+            assets: None,
+            meta: Some(vec![]),
             reward_account: None,
         }
     ));
@@ -40,15 +40,15 @@ fn video_creation_successful() {
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             },
             Ok(()),
         );
 
         let params = VideoCreationParametersRecord {
-            assets: NewAssets::<Test>::Upload(CreationUploadParameters {
+            assets: Some(StorageAssetsRecord {
                 object_creation_list: vec![
                     DataObjectCreationParameters {
                         size: 3,
@@ -65,7 +65,7 @@ fn video_creation_successful() {
                 ],
                 expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
             }),
-            meta: b"test".to_vec(),
+            meta: Some(b"test".to_vec()),
         };
 
         create_video_mock(
@@ -94,15 +94,16 @@ fn video_update_successful() {
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![]),
-                meta: vec![],
+                assets: None,
+                meta: Some(vec![]),
                 reward_account: None,
             },
             Ok(()),
         );
 
+        // create video with 3 assets
         let params = VideoCreationParametersRecord {
-            assets: NewAssets::<Test>::Upload(CreationUploadParameters {
+            assets: Some(StorageAssetsRecord {
                 object_creation_list: vec![
                     DataObjectCreationParameters {
                         size: 3,
@@ -119,11 +120,13 @@ fn video_update_successful() {
                 ],
                 expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
             }),
-            meta: b"test".to_vec(),
+            meta: Some(b"test".to_vec()),
         };
 
         let video_id = Content::next_video_id();
 
+        let first_obj_id = Storage::<Test>::next_data_object_id();
+
         create_video_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
@@ -132,17 +135,21 @@ fn video_update_successful() {
             Ok(()),
         );
 
+        // add 1 asset
         let update_params = VideoUpdateParametersRecord {
-            assets: Some(NewAssets::<Test>::Upload(CreationUploadParameters {
+            assets_to_upload: Some(StorageAssetsRecord {
                 object_creation_list: vec![DataObjectCreationParameters {
                     size: 3,
                     ipfs_content_id: b"first".to_vec(),
                 }],
                 expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-            })),
+            }),
             new_meta: None,
+            assets_to_remove: BTreeSet::new(),
         };
 
+        let last_obj_id = Storage::<Test>::next_data_object_id();
+
         update_video_mock(
             FIRST_MEMBER_ORIGIN,
             ContentActor::Member(FIRST_MEMBER_ID),
@@ -150,6 +157,19 @@ fn video_update_successful() {
             update_params,
             Ok(()),
         );
+
+        // remove all assets from the channel the video is in
+        update_video_mock(
+            FIRST_MEMBER_ORIGIN,
+            ContentActor::Member(FIRST_MEMBER_ID),
+            video_id,
+            VideoUpdateParametersRecord {
+                assets_to_upload: None,
+                new_meta: None,
+                assets_to_remove: (first_obj_id..last_obj_id).collect::<BTreeSet<_>>(),
+            },
+            Ok(()),
+        );
     })
 }
 
@@ -166,8 +186,8 @@ fn member_can_create_videos() {
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
             VideoCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![vec![b"https://somewhere.com/".to_vec()]]),
-                meta: b"metablob".to_vec(),
+                assets: None,
+                meta: None,
             }
         ));
 
@@ -178,8 +198,8 @@ fn member_can_create_videos() {
                 channel_id,
                 video_id,
                 VideoCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![vec![b"https://somewhere.com/".to_vec()]]),
-                    meta: b"metablob".to_vec(),
+                    assets: None,
+                    meta: None,
                 }
             ))
         );
@@ -194,11 +214,10 @@ fn member_can_create_videos() {
             ContentActor::Member(FIRST_MEMBER_ID),
             video_id,
             VideoUpdateParametersRecord {
-                assets: Some(NewAssets::<Test>::Urls(vec![vec![
-                    b"https://somewhere-else.com/".to_vec()
-                ]])),
-                new_meta: Some(b"newmetablob".to_vec()),
-            }
+                assets_to_upload: None,
+                new_meta: None,
+                assets_to_remove: BTreeSet::new(),
+            },
         ));
 
         assert_eq!(
@@ -207,10 +226,9 @@ fn member_can_create_videos() {
                 ContentActor::Member(FIRST_MEMBER_ID),
                 video_id,
                 VideoUpdateParametersRecord {
-                    assets: Some(NewAssets::<Test>::Urls(vec![vec![
-                        b"https://somewhere-else.com/".to_vec()
-                    ]])),
-                    new_meta: Some(b"newmetablob".to_vec()),
+                    assets_to_upload: None,
+                    new_meta: None,
+                    assets_to_remove: BTreeSet::new(),
                 }
             ))
         );
@@ -222,8 +240,8 @@ fn member_can_create_videos() {
                 ContentActor::Member(SECOND_MEMBER_ID),
                 channel_id,
                 VideoCreationParametersRecord {
-                    assets: NewAssets::<Test>::Urls(vec![]),
-                    meta: vec![],
+                    assets: None,
+                    meta: None,
                 }
             ),
             Error::<Test>::ActorNotAuthorized
@@ -236,9 +254,10 @@ fn member_can_create_videos() {
                 ContentActor::Member(SECOND_MEMBER_ID),
                 video_id,
                 VideoUpdateParametersRecord {
-                    assets: None,
+                    assets_to_upload: None,
                     new_meta: None,
-                }
+                    assets_to_remove: BTreeSet::new(),
+                },
             ),
             Error::<Test>::ActorNotAuthorized
         );
@@ -248,7 +267,8 @@ fn member_can_create_videos() {
             Content::delete_video(
                 Origin::signed(SECOND_MEMBER_ORIGIN),
                 ContentActor::Member(SECOND_MEMBER_ID),
-                video_id
+                video_id,
+                BTreeSet::new(),
             ),
             Error::<Test>::ActorNotAuthorized
         );
@@ -257,7 +277,8 @@ fn member_can_create_videos() {
         assert_ok!(Content::delete_video(
             Origin::signed(FIRST_MEMBER_ORIGIN),
             ContentActor::Member(FIRST_MEMBER_ID),
-            video_id
+            video_id,
+            BTreeSet::new(),
         ));
 
         assert_eq!(
@@ -283,8 +304,8 @@ fn curators_can_censor_videos() {
             ContentActor::Member(FIRST_MEMBER_ID),
             channel_id,
             VideoCreationParametersRecord {
-                assets: NewAssets::<Test>::Urls(vec![vec![b"https://somewhere.com/".to_vec()]]),
-                meta: b"metablob".to_vec(),
+                assets: None,
+                meta: None,
             }
         ));
 

+ 3 - 1
runtime-modules/storage/src/lib.rs

@@ -1012,7 +1012,8 @@ decl_event! {
         /// Params
         /// - data objects IDs
         /// - initial uploading parameters
-        DataObjectsUploaded(Vec<DataObjectId>, UploadParameters),
+        /// - deletion prize for objects
+        DataObjectsUploaded(Vec<DataObjectId>, UploadParameters, Balance),
 
         /// Emits on setting the storage operator metadata.
         /// Params
@@ -2581,6 +2582,7 @@ impl<T: Trait> DataObjectStorage<T> for Module<T> {
         Self::deposit_event(RawEvent::DataObjectsUploaded(
             data.data_objects_map.keys().cloned().collect(),
             params,
+            T::DataObjectDeletionPrize::get(),
         ));
 
         Ok(())

+ 1 - 0
runtime-modules/storage/src/tests/mod.rs

@@ -712,6 +712,7 @@ fn upload_succeeded() {
         EventFixture::assert_last_crate_event(RawEvent::DataObjectsUploaded(
             vec![data_object_id],
             upload_params,
+            DataObjectDeletionPrize::get(),
         ));
     });
 }

File diff suppressed because it is too large
+ 1 - 1
types/augment-codec/all.ts


+ 4 - 0
types/augment-codec/augment-api-errors.ts

@@ -138,6 +138,10 @@ declare module '@polkadot/api/types/errors' {
        * Channel assets feasibility
        **/
       InvalidAssetsProvided: AugmentedError<ApiType>;
+      /**
+       * Bag Size specified is not valid
+       **/
+      InvalidBagSizeSpecified: AugmentedError<ApiType>;
       /**
        * Lead authentication failed
        **/

+ 7 - 6
types/augment-codec/augment-api-events.ts

@@ -2,7 +2,7 @@
 /* eslint-disable */
 
 import type { BTreeMap, BTreeSet, Bytes, Option, Vec, bool, u32, u64 } from '@polkadot/types';
-import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, NewAssets, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
+import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageAssets, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
 import type { BalanceStatus } from '@polkadot/types/interfaces/balances';
 import type { AuthorityId } from '@polkadot/types/interfaces/consensus';
 import type { AuthorityList } from '@polkadot/types/interfaces/grandpa';
@@ -69,15 +69,15 @@ declare module '@polkadot/api/types/events' {
       CuratorGroupStatusSet: AugmentedEvent<ApiType, [CuratorGroupId, bool]>;
       CuratorRemoved: AugmentedEvent<ApiType, [CuratorGroupId, CuratorId]>;
       FeaturedVideosSet: AugmentedEvent<ApiType, [ContentActor, Vec<VideoId>]>;
-      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonCreationParameters]>;
+      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, StorageAssets, PersonCreationParameters]>;
       PersonDeleted: AugmentedEvent<ApiType, [ContentActor, PersonId]>;
-      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonUpdateParameters]>;
+      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, StorageAssets, PersonUpdateParameters]>;
       PlaylistCreated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistCreationParameters]>;
       PlaylistDeleted: AugmentedEvent<ApiType, [ContentActor, PlaylistId]>;
       PlaylistUpdated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistUpdateParameters]>;
-      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
+      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, StorageAssets, SeriesParameters, Series]>;
       SeriesDeleted: AugmentedEvent<ApiType, [ContentActor, SeriesId]>;
-      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
+      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, StorageAssets, SeriesParameters, Series]>;
       VideoCategoryCreated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryCreationParameters]>;
       VideoCategoryDeleted: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId]>;
       VideoCategoryUpdated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryUpdateParameters]>;
@@ -1098,8 +1098,9 @@ declare module '@polkadot/api/types/events' {
        * Params
        * - data objects IDs
        * - initial uploading parameters
+       * - deletion prize for objects
        **/
-      DataObjectsUploaded: AugmentedEvent<ApiType, [Vec<DataObjectId>, UploadParameters]>;
+      DataObjectsUploaded: AugmentedEvent<ApiType, [Vec<DataObjectId>, UploadParameters, Balance]>;
       /**
        * Emits on creating distribution bucket.
        * Params

+ 4 - 8
types/augment-codec/augment-api-tx.ts

@@ -137,17 +137,13 @@ declare module '@polkadot/api/types/submittable' {
       createSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: SeriesParameters | { assets?: any; seasons?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, SeriesParameters]>;
       createVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: VideoCreationParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, VideoCreationParameters]>;
       createVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, params: VideoCategoryCreationParameters | { meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryCreationParameters]>;
-      deleteChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId]>;
+      deleteChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, numObjectsToDelete: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, u64]>;
       deleteChannelCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: ChannelCategoryId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelCategoryId]>;
       deletePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PersonActor, PersonId]>;
       deletePlaylist: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, PlaylistId]>;
       deleteSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, series: SeriesId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, SeriesId]>;
-      deleteVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId]>;
+      deleteVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, assetsToRemove: BTreeSet<DataObjectId>) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, BTreeSet<DataObjectId>]>;
       deleteVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: VideoCategoryId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryId]>;
-      /**
-       * Remove assets of a channel from storage
-       **/
-      removeChannelAssets: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, assets: BTreeSet<DataObjectId>) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, BTreeSet<DataObjectId>]>;
       /**
        * Remove curator from a given curator group
        **/
@@ -159,13 +155,13 @@ declare module '@polkadot/api/types/submittable' {
        **/
       setCuratorGroupStatus: AugmentedSubmittable<(curatorGroupId: CuratorGroupId | AnyNumber | Uint8Array, isActive: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [CuratorGroupId, bool]>;
       setFeaturedVideos: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, list: Vec<VideoId> | (VideoId | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [ContentActor, Vec<VideoId>]>;
-      updateChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets?: any; new_meta?: any; reward_account?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, ChannelUpdateParameters]>;
+      updateChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets_to_upload?: any; new_meta?: any; reward_account?: any; assets_to_remove?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, ChannelUpdateParameters]>;
       updateChannelCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: ChannelCategoryId | AnyNumber | Uint8Array, params: ChannelCategoryUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelCategoryId, ChannelCategoryUpdateParameters]>;
       updateChannelCensorshipStatus: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, isCensored: bool | boolean | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, bool, Bytes]>;
       updatePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array, params: PersonUpdateParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [PersonActor, PersonId, PersonUpdateParameters]>;
       updatePlaylist: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array, params: PlaylistUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, PlaylistId, PlaylistUpdateParameters]>;
       updateSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: SeriesParameters | { assets?: any; seasons?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, SeriesParameters]>;
-      updateVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, params: VideoUpdateParameters | { assets?: any; new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, VideoUpdateParameters]>;
+      updateVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, params: VideoUpdateParameters | { assets_to_upload?: any; new_meta?: any; assets_to_remove?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, VideoUpdateParameters]>;
       updateVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: VideoCategoryId | AnyNumber | Uint8Array, params: VideoCategoryUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryId, VideoCategoryUpdateParameters]>;
       updateVideoCensorshipStatus: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, isCensored: bool | boolean | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, bool, Bytes]>;
     };

File diff suppressed because it is too large
+ 0 - 0
types/augment-codec/augment-types.ts


+ 17 - 24
types/augment/all/defs.json

@@ -765,24 +765,16 @@
             "Lead": "Null"
         }
     },
-    "CreationUploadParameters": {
+    "StorageAssets": {
         "object_creation_list": "Vec<DataObjectCreationParameters>",
         "expected_data_size_fee": "u128"
     },
-    "AssetUrls": "Vec<Url>",
-    "NewAssets": {
-        "_enum": {
-            "Upload": "CreationUploadParameters",
-            "Urls": "Vec<AssetUrls>"
-        }
-    },
     "Channel": {
         "owner": "ChannelOwner",
         "num_videos": "u64",
         "is_censored": "bool",
         "reward_account": "Option<GenericAccountId>",
-        "deletion_prize_source_account_id": "GenericAccountId",
-        "num_assets": "u64"
+        "deletion_prize_source_account_id": "GenericAccountId"
     },
     "ChannelOwner": {
         "_enum": {
@@ -799,14 +791,15 @@
         "new_meta": "Bytes"
     },
     "ChannelCreationParameters": {
-        "assets": "NewAssets",
-        "meta": "Bytes",
+        "assets": "Option<StorageAssets>",
+        "meta": "Option<Bytes>",
         "reward_account": "Option<GenericAccountId>"
     },
     "ChannelUpdateParameters": {
-        "assets": "Option<NewAssets>",
+        "assets_to_upload": "Option<StorageAssets>",
         "new_meta": "Option<Bytes>",
-        "reward_account": "Option<Option<GenericAccountId>>"
+        "reward_account": "Option<Option<GenericAccountId>>",
+        "assets_to_remove": "Vec<DataObjectId>"
     },
     "ChannelOwnershipTransferRequestId": "u64",
     "ChannelOwnershipTransferRequest": {
@@ -818,8 +811,7 @@
     "Video": {
         "in_channel": "ChannelId",
         "in_series": "Option<SeriesId>",
-        "is_censored": "bool",
-        "maybe_data_objects_id_set": "Option<Vec<DataObjectId>>"
+        "is_censored": "bool"
     },
     "VideoId": "u64",
     "VideoCategoryId": "u64",
@@ -831,12 +823,13 @@
         "new_meta": "Bytes"
     },
     "VideoCreationParameters": {
-        "assets": "NewAssets",
-        "meta": "Bytes"
+        "assets": "Option<StorageAssets>",
+        "meta": "Option<Bytes>"
     },
     "VideoUpdateParameters": {
-        "assets": "Option<NewAssets>",
-        "new_meta": "Option<Bytes>"
+        "assets_to_upload": "Option<StorageAssets>",
+        "new_meta": "Option<Bytes>",
+        "assets_to_remove": "Vec<DataObjectId>"
     },
     "Person": {
         "controlled_by": "PersonController"
@@ -855,11 +848,11 @@
         }
     },
     "PersonCreationParameters": {
-        "assets": "NewAssets",
+        "assets": "StorageAssets",
         "meta": "Bytes"
     },
     "PersonUpdateParameters": {
-        "assets": "Option<NewAssets>",
+        "assets": "Option<StorageAssets>",
         "meta": "Option<Bytes>"
     },
     "Playlist": {
@@ -881,12 +874,12 @@
         "episodes": "Vec<VideoId>"
     },
     "SeriesParameters": {
-        "assets": "Option<NewAssets>",
+        "assets": "Option<StorageAssets>",
         "seasons": "Option<Vec<Option<SeasonParameters>>>",
         "meta": "Option<Bytes>"
     },
     "SeasonParameters": {
-        "assets": "Option<NewAssets>",
+        "assets": "Option<StorageAssets>",
         "episodes": "Option<Vec<Option<EpisodeParemters>>>",
         "meta": "Option<Bytes>"
     },

+ 18 - 29
types/augment/all/types.ts

@@ -139,9 +139,6 @@ export interface Approved extends Enum {
   readonly asExecutionFailed: ExecutionFailed;
 }
 
-/** @name AssetUrls */
-export interface AssetUrls extends Vec<Url> {}
-
 /** @name Backer */
 export interface Backer extends Struct {
   readonly member: GenericAccountId;
@@ -209,7 +206,6 @@ export interface Channel extends Struct {
   readonly is_censored: bool;
   readonly reward_account: Option<GenericAccountId>;
   readonly deletion_prize_source_account_id: GenericAccountId;
-  readonly num_assets: u64;
 }
 
 /** @name ChannelCategory */
@@ -233,8 +229,8 @@ export interface ChannelContentType extends Null {}
 
 /** @name ChannelCreationParameters */
 export interface ChannelCreationParameters extends Struct {
-  readonly assets: NewAssets;
-  readonly meta: Bytes;
+  readonly assets: Option<StorageAssets>;
+  readonly meta: Option<Bytes>;
   readonly reward_account: Option<GenericAccountId>;
 }
 
@@ -268,9 +264,10 @@ export interface ChannelPublicationStatus extends Null {}
 
 /** @name ChannelUpdateParameters */
 export interface ChannelUpdateParameters extends Struct {
-  readonly assets: Option<NewAssets>;
+  readonly assets_to_upload: Option<StorageAssets>;
   readonly new_meta: Option<Bytes>;
   readonly reward_account: Option<Option<GenericAccountId>>;
+  readonly assets_to_remove: Vec<DataObjectId>;
 }
 
 /** @name ChildPositionInParentCategory */
@@ -315,12 +312,6 @@ export interface ContentIdSet extends BTreeSet<Cid> {}
 /** @name CreateEntityOperation */
 export interface CreateEntityOperation extends Null {}
 
-/** @name CreationUploadParameters */
-export interface CreationUploadParameters extends Struct {
-  readonly object_creation_list: Vec<DataObjectCreationParameters>;
-  readonly expected_data_size_fee: u128;
-}
-
 /** @name Credential */
 export interface Credential extends Null {}
 
@@ -655,14 +646,6 @@ export interface ModerationAction extends Struct {
   readonly rationale: Text;
 }
 
-/** @name NewAssets */
-export interface NewAssets extends Enum {
-  readonly isUpload: boolean;
-  readonly asUpload: CreationUploadParameters;
-  readonly isUrls: boolean;
-  readonly asUrls: Vec<AssetUrls>;
-}
-
 /** @name NextAdjustment */
 export interface NextAdjustment extends Struct {
   readonly adjustment: AdjustOnInterval;
@@ -782,7 +765,7 @@ export interface PersonController extends Enum {
 
 /** @name PersonCreationParameters */
 export interface PersonCreationParameters extends Struct {
-  readonly assets: NewAssets;
+  readonly assets: StorageAssets;
   readonly meta: Bytes;
 }
 
@@ -791,7 +774,7 @@ export interface PersonId extends u64 {}
 
 /** @name PersonUpdateParameters */
 export interface PersonUpdateParameters extends Struct {
-  readonly assets: Option<NewAssets>;
+  readonly assets: Option<StorageAssets>;
   readonly meta: Option<Bytes>;
 }
 
@@ -1080,7 +1063,7 @@ export interface Season extends Struct {
 
 /** @name SeasonParameters */
 export interface SeasonParameters extends Struct {
-  readonly assets: Option<NewAssets>;
+  readonly assets: Option<StorageAssets>;
   readonly episodes: Option<Vec<Option<EpisodeParemters>>>;
   readonly meta: Option<Bytes>;
 }
@@ -1106,7 +1089,7 @@ export interface SeriesId extends u64 {}
 
 /** @name SeriesParameters */
 export interface SeriesParameters extends Struct {
-  readonly assets: Option<NewAssets>;
+  readonly assets: Option<StorageAssets>;
   readonly seasons: Option<Vec<Option<SeasonParameters>>>;
   readonly meta: Option<Bytes>;
 }
@@ -1206,6 +1189,12 @@ export interface StaticBagId extends Enum {
 /** @name Status */
 export interface Status extends Null {}
 
+/** @name StorageAssets */
+export interface StorageAssets extends Struct {
+  readonly object_creation_list: Vec<DataObjectCreationParameters>;
+  readonly expected_data_size_fee: u128;
+}
+
 /** @name StorageBucket */
 export interface StorageBucket extends Struct {
   readonly operator_status: StorageBucketOperatorStatus;
@@ -1330,7 +1319,6 @@ export interface Video extends Struct {
   readonly in_channel: ChannelId;
   readonly in_series: Option<SeriesId>;
   readonly is_censored: bool;
-  readonly maybe_data_objects_id_set: Option<Vec<DataObjectId>>;
 }
 
 /** @name VideoCategory */
@@ -1351,8 +1339,8 @@ export interface VideoCategoryUpdateParameters extends Struct {
 
 /** @name VideoCreationParameters */
 export interface VideoCreationParameters extends Struct {
-  readonly assets: NewAssets;
-  readonly meta: Bytes;
+  readonly assets: Option<StorageAssets>;
+  readonly meta: Option<Bytes>;
 }
 
 /** @name VideoId */
@@ -1360,8 +1348,9 @@ export interface VideoId extends u64 {}
 
 /** @name VideoUpdateParameters */
 export interface VideoUpdateParameters extends Struct {
-  readonly assets: Option<NewAssets>;
+  readonly assets_to_upload: Option<StorageAssets>;
   readonly new_meta: Option<Bytes>;
+  readonly assets_to_remove: Vec<DataObjectId>;
 }
 
 /** @name VoteKind */

+ 4 - 0
types/augment/augment-api-errors.ts

@@ -138,6 +138,10 @@ declare module '@polkadot/api/types/errors' {
        * Channel assets feasibility
        **/
       InvalidAssetsProvided: AugmentedError<ApiType>;
+      /**
+       * Bag Size specified is not valid
+       **/
+      InvalidBagSizeSpecified: AugmentedError<ApiType>;
       /**
        * Lead authentication failed
        **/

+ 7 - 6
types/augment/augment-api-events.ts

@@ -2,7 +2,7 @@
 /* eslint-disable */
 
 import type { BTreeMap, BTreeSet, Bytes, Option, Vec, bool, u32, u64 } from '@polkadot/types';
-import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, NewAssets, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
+import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageAssets, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
 import type { BalanceStatus } from '@polkadot/types/interfaces/balances';
 import type { AuthorityId } from '@polkadot/types/interfaces/consensus';
 import type { AuthorityList } from '@polkadot/types/interfaces/grandpa';
@@ -69,15 +69,15 @@ declare module '@polkadot/api/types/events' {
       CuratorGroupStatusSet: AugmentedEvent<ApiType, [CuratorGroupId, bool]>;
       CuratorRemoved: AugmentedEvent<ApiType, [CuratorGroupId, CuratorId]>;
       FeaturedVideosSet: AugmentedEvent<ApiType, [ContentActor, Vec<VideoId>]>;
-      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonCreationParameters]>;
+      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, StorageAssets, PersonCreationParameters]>;
       PersonDeleted: AugmentedEvent<ApiType, [ContentActor, PersonId]>;
-      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonUpdateParameters]>;
+      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, StorageAssets, PersonUpdateParameters]>;
       PlaylistCreated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistCreationParameters]>;
       PlaylistDeleted: AugmentedEvent<ApiType, [ContentActor, PlaylistId]>;
       PlaylistUpdated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistUpdateParameters]>;
-      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
+      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, StorageAssets, SeriesParameters, Series]>;
       SeriesDeleted: AugmentedEvent<ApiType, [ContentActor, SeriesId]>;
-      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
+      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, StorageAssets, SeriesParameters, Series]>;
       VideoCategoryCreated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryCreationParameters]>;
       VideoCategoryDeleted: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId]>;
       VideoCategoryUpdated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryUpdateParameters]>;
@@ -1098,8 +1098,9 @@ declare module '@polkadot/api/types/events' {
        * Params
        * - data objects IDs
        * - initial uploading parameters
+       * - deletion prize for objects
        **/
-      DataObjectsUploaded: AugmentedEvent<ApiType, [Vec<DataObjectId>, UploadParameters]>;
+      DataObjectsUploaded: AugmentedEvent<ApiType, [Vec<DataObjectId>, UploadParameters, Balance]>;
       /**
        * Emits on creating distribution bucket.
        * Params

+ 4 - 8
types/augment/augment-api-tx.ts

@@ -137,17 +137,13 @@ declare module '@polkadot/api/types/submittable' {
       createSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: SeriesParameters | { assets?: any; seasons?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, SeriesParameters]>;
       createVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: VideoCreationParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, VideoCreationParameters]>;
       createVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, params: VideoCategoryCreationParameters | { meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryCreationParameters]>;
-      deleteChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId]>;
+      deleteChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, numObjectsToDelete: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, u64]>;
       deleteChannelCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: ChannelCategoryId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelCategoryId]>;
       deletePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PersonActor, PersonId]>;
       deletePlaylist: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, PlaylistId]>;
       deleteSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, series: SeriesId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, SeriesId]>;
-      deleteVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId]>;
+      deleteVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, assetsToRemove: BTreeSet<DataObjectId>) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, BTreeSet<DataObjectId>]>;
       deleteVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: VideoCategoryId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryId]>;
-      /**
-       * Remove assets of a channel from storage
-       **/
-      removeChannelAssets: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, assets: BTreeSet<DataObjectId>) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, BTreeSet<DataObjectId>]>;
       /**
        * Remove curator from a given curator group
        **/
@@ -159,13 +155,13 @@ declare module '@polkadot/api/types/submittable' {
        **/
       setCuratorGroupStatus: AugmentedSubmittable<(curatorGroupId: CuratorGroupId | AnyNumber | Uint8Array, isActive: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [CuratorGroupId, bool]>;
       setFeaturedVideos: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, list: Vec<VideoId> | (VideoId | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [ContentActor, Vec<VideoId>]>;
-      updateChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets?: any; new_meta?: any; reward_account?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, ChannelUpdateParameters]>;
+      updateChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets_to_upload?: any; new_meta?: any; reward_account?: any; assets_to_remove?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, ChannelUpdateParameters]>;
       updateChannelCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: ChannelCategoryId | AnyNumber | Uint8Array, params: ChannelCategoryUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelCategoryId, ChannelCategoryUpdateParameters]>;
       updateChannelCensorshipStatus: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, isCensored: bool | boolean | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, bool, Bytes]>;
       updatePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array, params: PersonUpdateParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [PersonActor, PersonId, PersonUpdateParameters]>;
       updatePlaylist: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array, params: PlaylistUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, PlaylistId, PlaylistUpdateParameters]>;
       updateSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: SeriesParameters | { assets?: any; seasons?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, SeriesParameters]>;
-      updateVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, params: VideoUpdateParameters | { assets?: any; new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, VideoUpdateParameters]>;
+      updateVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, params: VideoUpdateParameters | { assets_to_upload?: any; new_meta?: any; assets_to_remove?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, VideoUpdateParameters]>;
       updateVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: VideoCategoryId | AnyNumber | Uint8Array, params: VideoCategoryUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryId, VideoCategoryUpdateParameters]>;
       updateVideoCensorshipStatus: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, isCensored: bool | boolean | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoId, bool, Bytes]>;
     };

File diff suppressed because it is too large
+ 0 - 0
types/augment/augment-types.ts


+ 15 - 24
types/src/content/index.ts

@@ -1,7 +1,7 @@
 import { Vec, Option, Tuple } from '@polkadot/types'
 import { bool, u64, u32, u128, Null, Bytes } from '@polkadot/types/primitive'
 import { MemberId } from '../members'
-import { JoyStructDecorated, JoyEnum, ChannelId, JoyBTreeSet, Url } from '../common'
+import { JoyStructDecorated, JoyEnum, ChannelId, JoyBTreeSet } from '../common'
 import { GenericAccountId as AccountId } from '@polkadot/types/generic/AccountId'
 import { DataObjectId, DataObjectCreationParameters } from '../storage'
 
@@ -17,18 +17,11 @@ export class ChannelOwnershipTransferRequestId extends u64 {}
 export class MaxNumber extends u32 {}
 export class IsCensored extends bool {}
 
-export class AssetUrls extends Vec.with(Url) {}
-
-export class CreationUploadParameters extends JoyStructDecorated({
+export class StorageAssets extends JoyStructDecorated({
   object_creation_list: Vec.with(DataObjectCreationParameters),
   expected_data_size_fee: u128,
 }) {}
 
-export class NewAssets extends JoyEnum({
-  Upload: CreationUploadParameters,
-  Urls: Vec.with(AssetUrls),
-}) {}
-
 export class CuratorGroup extends JoyStructDecorated({
   curators: JoyBTreeSet(CuratorId),
   active: bool,
@@ -51,19 +44,19 @@ export class Channel extends JoyStructDecorated({
   is_censored: bool,
   reward_account: Option.with(AccountId),
   deletion_prize_source_account_id: AccountId,
-  num_assets: u64,
 }) {}
 
 export class ChannelCreationParameters extends JoyStructDecorated({
-  assets: NewAssets,
-  meta: Bytes,
+  assets: Option.with(StorageAssets),
+  meta: Option.with(Bytes),
   reward_account: Option.with(AccountId),
 }) {}
 
 export class ChannelUpdateParameters extends JoyStructDecorated({
-  assets: Option.with(NewAssets),
+  assets_to_upload: Option.with(StorageAssets),
   new_meta: Option.with(Bytes),
   reward_account: Option.with(Option.with(AccountId)),
+  assets_to_remove: JoyBTreeSet(DataObjectId),
 }) {}
 
 export class ChannelOwnershipTransferRequest extends JoyStructDecorated({
@@ -101,17 +94,17 @@ export class Video extends JoyStructDecorated({
   in_channel: ChannelId,
   in_series: Option.with(SeriesId),
   is_censored: bool,
-  maybe_data_objects_id_set: Option.with(JoyBTreeSet(DataObjectId)),
 }) {}
 
 export class VideoCreationParameters extends JoyStructDecorated({
-  assets: NewAssets,
-  meta: Bytes,
+  assets: Option.with(StorageAssets),
+  meta: Option.with(Bytes),
 }) {}
 
 export class VideoUpdateParameters extends JoyStructDecorated({
-  assets: Option.with(NewAssets),
+  assets_to_upload: Option.with(StorageAssets),
   new_meta: Option.with(Bytes),
+  assets_to_remove: JoyBTreeSet(DataObjectId),
 }) {}
 
 export class Playlist extends JoyStructDecorated({
@@ -136,7 +129,7 @@ export class Season extends JoyStructDecorated({
 }) {}
 
 export class SeasonParameters extends JoyStructDecorated({
-  assets: Option.with(NewAssets),
+  assets: Option.with(StorageAssets),
   episodes: Option.with(Vec.with(Option.with(EpisodeParemters))),
   meta: Option.with(Bytes),
 }) {}
@@ -147,7 +140,7 @@ export class Series extends JoyStructDecorated({
 }) {}
 
 export class SeriesParameters extends JoyStructDecorated({
-  assets: Option.with(NewAssets),
+  assets: Option.with(StorageAssets),
   seasons: Option.with(Vec.with(Option.with(SeasonParameters))),
   meta: Option.with(Bytes),
 }) {}
@@ -162,12 +155,12 @@ export class Person extends JoyStructDecorated({
 }) {}
 
 export class PersonCreationParameters extends JoyStructDecorated({
-  assets: NewAssets,
+  assets: StorageAssets,
   meta: Bytes,
 }) {}
 
 export class PersonUpdateParameters extends JoyStructDecorated({
-  assets: Option.with(NewAssets),
+  assets: Option.with(StorageAssets),
   meta: Option.with(Bytes),
 }) {}
 
@@ -181,9 +174,7 @@ export const contentTypes = {
   CuratorGroupId,
   CuratorGroup,
   ContentActor,
-  CreationUploadParameters,
-  AssetUrls,
-  NewAssets,
+  StorageAssets,
   Channel,
   ChannelOwner,
   ChannelCategoryId,

+ 10 - 3
types/src/index.ts

@@ -1,4 +1,4 @@
-import { Codec, RegistryTypes } from '@polkadot/types/types'
+import { Codec, Constructor, RegistryTypes } from '@polkadot/types/types'
 import common from './common'
 import members from './members'
 import council from './council'
@@ -62,8 +62,8 @@ registry.register(types)
 // will create a type like: { a: string } | { b: number } | { c: Null } | "c"
 type EnumVariant<T> = keyof T extends infer K
   ? K extends keyof T
-    ? T[K] extends Null
-      ? K
+    ? T[K] extends Null | null
+      ? K | { [I in K]: T[I] }
       : { [I in K]: T[I] }
     : never
   : never
@@ -86,6 +86,8 @@ type CreateInterface_NoOption<T extends Codec> =
       ? CreateInterface<S>[]
       : T extends BTreeMap<infer K, infer V>
       ? Map<K, V>
+      : T extends Null
+      ? null
       : unknown)
 
 // Wrapper for CreateInterface_NoOption that includes resolving an Option
@@ -102,3 +104,8 @@ export function createType<TN extends AnyTypeName, T extends InterfaceTypes[TN]
 ): InterfaceTypes[TN] {
   return registry.createType(type, value)
 }
+
+// FIXME: Backward-compatibility. Use only one createType in the future!
+export function createTypeFromConstructor<T extends Codec>(type: Constructor<T>, value: CreateInterface<T>): T {
+  return registry.createType(type.name as AnyTypeName, value) as T
+}

Some files were not shown because too many files changed in this diff