diff --git a/bucket/ddc_bucket/account/store.rs b/bucket/ddc_bucket/account/store.rs index 18a69245..fff58bbe 100644 --- a/bucket/ddc_bucket/account/store.rs +++ b/bucket/ddc_bucket/account/store.rs @@ -9,12 +9,12 @@ use crate::ddc_bucket::{ }; use crate::ddc_bucket::currency::CurrencyConverter; use crate::ddc_bucket::flow::Flow; -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use ink_prelude::vec::Vec; use super::entity::Account; #[derive(Default, SpreadLayout, SpreadAllocate)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct AccountStore( pub Mapping, pub CurrencyConverter, diff --git a/bucket/ddc_bucket/bucket/entity.rs b/bucket/ddc_bucket/bucket/entity.rs index e6adc099..53bd923c 100644 --- a/bucket/ddc_bucket/bucket/entity.rs +++ b/bucket/ddc_bucket/bucket/entity.rs @@ -1,6 +1,7 @@ //! The data structure of Buckets. use ink_prelude::vec::Vec; +use ink_prelude::string::String; use ink_storage::traits::{SpreadAllocate, PackedAllocate, PackedLayout, SpreadLayout}; use scale::{Decode, Encode}; use ink_primitives::Key; @@ -10,10 +11,10 @@ use crate::ddc_bucket::{ }; use crate::ddc_bucket::flow::Flow; use crate::ddc_bucket::node::entity::Resource; -use crate::ddc_bucket::params::store::Params; + pub type BucketId = u32; -pub type BucketParams = Params; +pub type BucketParams = String; #[derive(Clone, PartialEq, Encode, Decode, SpreadAllocate, SpreadLayout, PackedLayout)] #[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))] @@ -24,6 +25,7 @@ pub struct Bucket { pub resource_reserved: Resource, pub public_availability: bool, pub resource_consumption_cap: Resource, + pub bucket_params: BucketParams } // https://use.ink/3.x/ink-vs-solidity#nested-mappings--custom--advanced-structures @@ -58,6 +60,8 @@ pub struct BucketStatus { pub rent_covered_until_ms: u64, } +pub const BUCKET_PARAMS_MAX_LEN: usize = 100_000; + impl Bucket { pub fn only_owner(&self, caller: AccountId) -> Result<()> { if self.owner_id == caller { Ok(()) } else { Err(OnlyOwner) } @@ -78,6 +82,15 @@ impl Bucket { pub fn change_owner(&mut self, owner_id: AccountId) { self.owner_id = owner_id; } + + pub fn set_params(&mut self, bucket_params: BucketParams) -> Result<()> { + if bucket_params.len() > BUCKET_PARAMS_MAX_LEN { + return Err(ParamsSizeExceedsLimit); + } + self.bucket_params = bucket_params; + Ok(()) + } + } impl From for BucketInStatus { diff --git a/bucket/ddc_bucket/bucket/messages.rs b/bucket/ddc_bucket/bucket/messages.rs index e7cd9155..0a55f498 100644 --- a/bucket/ddc_bucket/bucket/messages.rs +++ b/bucket/ddc_bucket/bucket/messages.rs @@ -3,7 +3,7 @@ use ink_lang::codegen::{EmitEvent, StaticEnv}; use ink_prelude::vec::Vec; -use crate::ddc_bucket::{AccountId, BucketAllocated, BucketCreated, BucketSettlePayment, BucketAvailabilityUpdated, DdcBucket, Result}; +use crate::ddc_bucket::{AccountId, BucketAllocated, BucketCreated, BucketSettlePayment, BucketAvailabilityUpdated, BucketParamsSet, DdcBucket, Result}; use crate::ddc_bucket::cluster::entity::{Cluster, ClusterId}; use crate::ddc_bucket::node::entity::Resource; @@ -13,25 +13,24 @@ impl DdcBucket { pub fn message_bucket_create(&mut self, bucket_params: BucketParams, cluster_id: ClusterId, owner_id: Option) -> Result { let owner_id = owner_id.unwrap_or(Self::env().caller()); self.accounts.create_if_not_exist(owner_id); - let bucket_id = self.buckets.create(owner_id, cluster_id); - let params_id = self.bucket_params.create(bucket_params)?; - assert_eq!(bucket_id, params_id); + let bucket_id = self.buckets.create(owner_id, cluster_id, bucket_params); Self::env().emit_event(BucketCreated { bucket_id, owner_id }); Ok(bucket_id) } pub fn message_bucket_change_owner(&mut self, bucket_id: BucketId, owner_id: AccountId) -> Result<()> { let caller = Self::env().caller(); - let bucket = self.buckets.get_mut(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; bucket.only_owner(caller)?; bucket.change_owner(owner_id); + self.buckets.update(bucket_id, &bucket)?; Ok(()) } pub fn message_bucket_alloc_into_cluster(&mut self, bucket_id: BucketId, resource: Resource) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; let mut cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; cluster.take_resource(resource)?; self.clusters.update(bucket.cluster_id, &cluster)?; @@ -42,13 +41,14 @@ impl DdcBucket { let now_ms = Self::env().block_timestamp(); self.accounts.increase_flow(now_ms, rent, &mut bucket.flow)?; + self.buckets.update(bucket_id, &bucket)?; Self::env().emit_event(BucketAllocated { bucket_id, cluster_id: bucket.cluster_id, resource }); Ok(()) } pub fn message_bucket_settle_payment(&mut self, bucket_id: BucketId) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; let now_ms = Self::env().block_timestamp(); let cash = self.accounts.settle_flow(now_ms, &mut bucket.flow)?; @@ -56,18 +56,21 @@ impl DdcBucket { let mut cluster = self.clusters.get(bucket.cluster_id)?; cluster.revenues.increase(cash); self.clusters.update(bucket.cluster_id, &cluster)?; + self.buckets.update(bucket_id, &bucket)?; Self::env().emit_event(BucketSettlePayment { bucket_id, cluster_id: bucket.cluster_id }); Ok(()) } - pub fn message_bucket_change_params(&mut self, bucket_id: BucketId, params: BucketParams) -> Result<()> { + pub fn message_bucket_change_params(&mut self, bucket_id: BucketId, bucket_params: BucketParams) -> Result<()> { let caller = Self::env().caller(); - let bucket = self.buckets.get(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; bucket.only_owner(caller)?; - - Self::impl_change_params(&mut self.bucket_params, bucket_id, params) + bucket.set_params(bucket_params.clone())?; + self.buckets.update(bucket_id, &bucket)?; + Self::env().emit_event(BucketParamsSet { bucket_id, bucket_params }); + Ok(()) } pub fn message_bucket_get(&self, bucket_id: BucketId) -> Result { @@ -78,7 +81,7 @@ impl DdcBucket { pub fn message_bucket_list(&self, offset: u32, limit: u32, filter_owner_id: Option) -> (Vec, u32) { let mut bucket_statuses = Vec::with_capacity(limit as usize); for bucket_id in offset..offset + limit { - let bucket = match self.buckets.0.get(bucket_id as usize) { + let bucket = match self.buckets.buckets.get(bucket_id) { None => break, // No more buckets, stop. Some(bucket) => bucket, }; @@ -95,89 +98,104 @@ impl DdcBucket { bucket_statuses.push(status), }; } - (bucket_statuses, self.buckets.0.len().try_into().unwrap()) + (bucket_statuses, self.buckets.next_bucket_id) } pub fn message_bucket_list_for_account(&self, owner_id: AccountId) -> Vec { - self.buckets.0 - .iter() - .filter(|bucket| bucket.owner_id == owner_id) - .cloned() - .collect() + let mut result : Vec = Vec::new(); + + for bucket_id in 0..self.buckets.next_bucket_id { + let bucket = self.buckets.get(bucket_id).unwrap(); + + if bucket.owner_id == owner_id { + result.push(bucket); + }; + } + + result } pub fn bucket_calculate_status(&self, bucket_id: BucketId, bucket: Bucket) -> Result { - let mut writer_ids = self.buckets_perms.get_bucket_readers(bucket_id); + let mut writer_ids = self.buckets.get_bucket_readers(bucket_id); writer_ids.push(bucket.owner_id); let rent_covered_until_ms = self.accounts.flow_covered_until(&bucket.flow)?; - let params = self.bucket_params.get(bucket_id)?.clone(); - let reader_ids = self.buckets_perms.get_bucket_readers(bucket_id); - Ok(BucketStatus { bucket_id, bucket: bucket.into(), params, writer_ids, reader_ids, rent_covered_until_ms }) + let reader_ids = self.buckets.get_bucket_readers(bucket_id); + let bucket_params = bucket.bucket_params.clone(); + + Ok(BucketStatus { bucket_id, params: bucket_params, bucket: bucket.into(), writer_ids, reader_ids, rent_covered_until_ms }) } pub fn message_bucket_set_resource_cap(&mut self, bucket_id: BucketId, new_resource_cap: Resource) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; let cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; bucket.set_cap(new_resource_cap); + self.buckets.update(bucket_id, &bucket)?; + Ok(()) } pub fn message_bucket_set_availability(&mut self, bucket_id: BucketId, public_availability: bool) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; let cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; bucket.set_availability(public_availability); + self.buckets.update(bucket_id, &bucket)?; + Self::env().emit_event(BucketAvailabilityUpdated { bucket_id, public_availability }); Ok(()) } pub fn message_get_bucket_writers(&mut self, bucket_id: BucketId) -> Result> { - let writers = self.buckets_perms.get_bucket_writers(bucket_id); + let writers = self.buckets.get_bucket_writers(bucket_id); Ok(writers) } pub fn message_grant_writer_permission(&mut self, bucket_id: BucketId, writer: AccountId) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let bucket = self.buckets.get(bucket_id)?; let cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; - self.buckets_perms.grant_writer_permission(bucket_id, writer).unwrap(); + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; + self.buckets.grant_writer_permission(bucket_id, writer).unwrap(); + Ok(()) } pub fn message_revoke_writer_permission(&mut self, bucket_id: BucketId, writer: AccountId) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let bucket = self.buckets.get(bucket_id)?; let cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; - self.buckets_perms.revoke_writer_permission(bucket_id, writer).unwrap(); + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; + self.buckets.revoke_writer_permission(bucket_id, writer).unwrap(); + Ok(()) } pub fn message_get_bucket_readers(&mut self, bucket_id: BucketId) -> Result> { - let readers = self.buckets_perms.get_bucket_readers(bucket_id); + let readers = self.buckets.get_bucket_readers(bucket_id); Ok(readers) } pub fn message_grant_reader_permission(&mut self, bucket_id: BucketId, reader: AccountId) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let bucket = self.buckets.get(bucket_id)?; let cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; - self.buckets_perms.grant_reader_permission(bucket_id, reader).unwrap(); + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; + self.buckets.grant_reader_permission(bucket_id, reader).unwrap(); + Ok(()) } pub fn message_revoke_reader_permission(&mut self, bucket_id: BucketId, reader: AccountId) -> Result<()> { - let bucket = self.buckets.get_mut(bucket_id)?; + let bucket = self.buckets.get(bucket_id)?; let cluster = self.clusters.get(bucket.cluster_id)?; - Self::only_owner_or_cluster_manager(bucket, &cluster)?; - self.buckets_perms.revoke_reader_permission(bucket_id, reader).unwrap(); + Self::only_owner_or_cluster_manager(&bucket, &cluster)?; + self.buckets.revoke_reader_permission(bucket_id, reader).unwrap(); + Ok(()) } diff --git a/bucket/ddc_bucket/bucket/store.rs b/bucket/ddc_bucket/bucket/store.rs index 311e6293..486b44bb 100644 --- a/bucket/ddc_bucket/bucket/store.rs +++ b/bucket/ddc_bucket/bucket/store.rs @@ -1,22 +1,29 @@ -//! The store to create and access Buckets. - -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use ink_prelude::vec::Vec; - +use ink_storage::Mapping; use crate::ddc_bucket::{AccountId, Error::*, Result}; use crate::ddc_bucket::cluster::entity::ClusterId; use crate::ddc_bucket::flow::Flow; use crate::ddc_bucket::schedule::Schedule; +use super::entity::{Bucket, BucketId, BucketParams}; + -use super::entity::{Bucket, BucketId}; #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] -pub struct BucketStore(pub Vec); +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] +pub struct BucketStore { + pub next_bucket_id: u32, + pub buckets: Mapping, + pub writers: Mapping>, + pub readers: Mapping> +} impl BucketStore { #[must_use] - pub fn create(&mut self, owner_id: AccountId, cluster_id: ClusterId) -> BucketId { + pub fn create(&mut self, owner_id: AccountId, cluster_id: ClusterId, bucket_params: BucketParams) -> BucketId { + let bucket_id = self.next_bucket_id; + self.next_bucket_id = self.next_bucket_id + 1; + let bucket = Bucket { owner_id, cluster_id, @@ -24,17 +31,96 @@ impl BucketStore { resource_reserved: 0, resource_consumption_cap: 0, public_availability: false, + bucket_params }; - let bucket_id: BucketId = self.0.len().try_into().unwrap(); - self.0.push(bucket); + + self.buckets.insert(&bucket_id, &bucket); bucket_id } - pub fn get(&self, bucket_id: BucketId) -> Result<&Bucket> { - self.0.get(bucket_id as usize).ok_or(BucketDoesNotExist) + pub fn get(&self, bucket_id: BucketId) -> Result { + self.buckets.get(bucket_id).ok_or(BucketDoesNotExist) + } + + pub fn update(&mut self, bucket_id: BucketId, bucket: &Bucket) -> Result<()> { + if !self.buckets.contains(&bucket_id) { + Err(BucketDoesNotExist) + } else { + self.buckets.insert(bucket_id, bucket); + Ok(()) + } } - pub fn get_mut(&mut self, bucket_id: BucketId) -> Result<&mut Bucket> { - self.0.get_mut(bucket_id as usize).ok_or(BucketDoesNotExist) + // get accounts with permission for bucket writing + pub fn get_bucket_writers(&self, key: BucketId) -> Vec { + let writers : Vec = self.writers.get(&key) + .unwrap_or(Vec::new()) + .iter() + .cloned() + .collect(); + return writers; } + + // grant permission for bucket writing for some account + pub fn grant_writer_permission(&mut self, key: BucketId, writer: AccountId) -> Result<()> { + if !self.writers.contains(&key) { + let empty_vec: Vec = Vec::new(); + self.writers.insert(key, &empty_vec); + } + + let mut writers = self.writers.get(&key).unwrap(); + writers.push(writer); + self.writers.insert(key, &writers); + + Ok(()) + } + + // revoke permission for bucket writing for some account + pub fn revoke_writer_permission(&mut self, key: BucketId, writer: AccountId) -> Result<()> { + let mut writers = self.writers.get(&key).unwrap(); + if let Some(pos) = writers.iter().position(|x| *x == writer) { + writers.remove(pos); + self.writers.insert(key, &writers); + } + + Ok(()) + } + + // get accounts with permission for bucket reading + pub fn get_bucket_readers(&self, key: BucketId) -> Vec { + let readers = self.readers.get(&key) + .unwrap_or(Vec::new()) + .iter() + .cloned() + .collect(); + + return readers; + } + + // grant permission for bucket reading for some account + pub fn grant_reader_permission(&mut self, key: BucketId, reader: AccountId) -> Result<()> { + if !self.readers.contains(&key) { + let empty_vec: Vec = Vec::new(); + self.readers.insert(key, &empty_vec); + } + + let mut readers = self.readers.get(&key).unwrap(); + readers.push(reader); + self.readers.insert(key, &readers); + + Ok(()) + } + + // revoke permission for bucket writing for some account + pub fn revoke_reader_permission(&mut self, key: BucketId, reader: AccountId) -> Result<()> { + let mut readers = self.readers.get(&key).unwrap(); + + if let Some(pos) = readers.iter().position(|x| *x == reader) { + readers.remove(pos); + self.readers.insert(key, &readers); + } + + Ok(()) + } + } diff --git a/bucket/ddc_bucket/buckets_perms/mod.rs b/bucket/ddc_bucket/buckets_perms/mod.rs deleted file mode 100644 index c8b20147..00000000 --- a/bucket/ddc_bucket/buckets_perms/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Bucket perms management. - -pub mod store; diff --git a/bucket/ddc_bucket/buckets_perms/store.rs b/bucket/ddc_bucket/buckets_perms/store.rs deleted file mode 100644 index 147baf90..00000000 --- a/bucket/ddc_bucket/buckets_perms/store.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! The store to adjust write/read permissions for DDC Buckets - -use crate::ddc_bucket::{AccountId, BucketId, Result}; - -use ink_prelude::vec::Vec; -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; -use ink_storage::Mapping; - -#[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] -pub struct BucketsPermsStore { - writers: Mapping>, - readers: Mapping> -} - -impl BucketsPermsStore { - - // get accounts with permission for bucket writing - pub fn get_bucket_writers(&self, key: BucketId) -> Vec { - let writers : Vec = self.writers.get(&key) - .unwrap_or(Vec::new()) - .iter() - .cloned() - .collect(); - return writers; - } - - // grant permission for bucket writing for some account - pub fn grant_writer_permission(&mut self, key: BucketId, writer: AccountId) -> Result<()> { - if !self.writers.contains(&key) { - let empty_vec: Vec = Vec::new(); - self.writers.insert(key, &empty_vec); - } - - let mut writers = self.writers.get(&key).unwrap(); - writers.push(writer); - self.writers.insert(key, &writers); - - Ok(()) - } - - // revoke permission for bucket writing for some account - pub fn revoke_writer_permission(&mut self, key: BucketId, writer: AccountId) -> Result<()> { - let mut writers = self.writers.get(&key).unwrap(); - if let Some(pos) = writers.iter().position(|x| *x == writer) { - writers.remove(pos); - self.writers.insert(key, &writers); - } - - Ok(()) - } - - // get accounts with permission for bucket reading - pub fn get_bucket_readers(&self, key: BucketId) -> Vec { - let readers = self.readers.get(&key) - .unwrap_or(Vec::new()) - .iter() - .cloned() - .collect(); - - return readers; - } - - // grant permission for bucket reading for some account - pub fn grant_reader_permission(&mut self, key: BucketId, reader: AccountId) -> Result<()> { - if !self.readers.contains(&key) { - let empty_vec: Vec = Vec::new(); - self.readers.insert(key, &empty_vec); - } - - let mut readers = self.readers.get(&key).unwrap(); - readers.push(reader); - self.readers.insert(key, &readers); - - Ok(()) - } - - // revoke permission for bucket writing for some account - pub fn revoke_reader_permission(&mut self, key: BucketId, reader: AccountId) -> Result<()> { - let mut readers = self.readers.get(&key).unwrap(); - - if let Some(pos) = readers.iter().position(|x| *x == reader) { - readers.remove(pos); - self.readers.insert(key, &readers); - } - - Ok(()) - } - -} diff --git a/bucket/ddc_bucket/cash.rs b/bucket/ddc_bucket/cash.rs index 9c76b8d9..20766771 100644 --- a/bucket/ddc_bucket/cash.rs +++ b/bucket/ddc_bucket/cash.rs @@ -2,7 +2,7 @@ //! //! These data structures facilitate the correctness of money-related calculations using the Rust type system. -use ink_storage::traits::{SpreadAllocate, SpreadLayout, PackedLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout, PackedLayout}; use ink_storage::traits::KeyPtr; use scale::{Decode, Encode}; @@ -13,7 +13,7 @@ use crate::ddc_bucket::Error::InsufficientBalance; /// Cash represents some value that was taken from someone, and that must be credited to someone. #[must_use] #[derive(Clone, Copy, PartialEq, Encode, Decode, SpreadLayout, PackedLayout)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct Cash(pub Balance); impl SpreadAllocate for Cash { diff --git a/bucket/ddc_bucket/cdn_node/entity.rs b/bucket/ddc_bucket/cdn_node/entity.rs index 717cd11a..7593f2d4 100644 --- a/bucket/ddc_bucket/cdn_node/entity.rs +++ b/bucket/ddc_bucket/cdn_node/entity.rs @@ -4,11 +4,12 @@ use ink_storage::traits::{SpreadAllocate, PackedLayout, SpreadLayout, PackedAllo use scale::{Decode, Encode}; use ink_primitives::Key; use crate::ddc_bucket::{AccountId, Balance, ClusterId, NodeStatusInCluster, Error::*, Result}; -use crate::ddc_bucket::params::store::Params; +use ink_prelude::string::String; + pub type ProviderId = AccountId; pub type CdnNodeKey = AccountId; -pub type CdnNodeParams = Params; +pub type CdnNodeParams = String; pub type Resource = u32; #[derive(Clone, PartialEq, Encode, Decode, SpreadAllocate, SpreadLayout, PackedLayout)] diff --git a/bucket/ddc_bucket/cdn_node/store.rs b/bucket/ddc_bucket/cdn_node/store.rs index d2d5d8f9..402df082 100644 --- a/bucket/ddc_bucket/cdn_node/store.rs +++ b/bucket/ddc_bucket/cdn_node/store.rs @@ -1,6 +1,6 @@ //! The store where to create and access Nodes. -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use ink_storage::Mapping; use ink_prelude::vec::Vec; @@ -9,7 +9,7 @@ use super::entity::{CdnNode, CdnNodeKey, CdnNodeParams}; #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct CdnNodeStore { pub cdn_nodes: Mapping, // This vector is temporal and must be replaced with an offchain indexer diff --git a/bucket/ddc_bucket/cluster/entity.rs b/bucket/ddc_bucket/cluster/entity.rs index 688e8c66..1aa5c7e6 100644 --- a/bucket/ddc_bucket/cluster/entity.rs +++ b/bucket/ddc_bucket/cluster/entity.rs @@ -1,18 +1,18 @@ //! The data structure of Clusters. use ink_prelude::vec::Vec; +use ink_prelude::string::String; use ink_storage::traits::{SpreadAllocate, SpreadLayout, PackedLayout, PackedAllocate}; use scale::{Decode, Encode}; use ink_primitives::Key; use crate::ddc_bucket::cash::{Cash, Payable}; use crate::ddc_bucket::node::entity::{Resource, NodeKey}; use crate::ddc_bucket::cdn_node::entity::{CdnNodeKey}; - -use crate::ddc_bucket::params::store::Params; use crate::ddc_bucket::Error::{OnlyClusterManager, InsufficientBalance}; use crate::ddc_bucket::{AccountId, Balance, VNodeToken, Result, Error::*}; + pub type ClusterId = u32; -pub type ClusterParams = Params; +pub type ClusterParams = String; #[derive(Clone, PartialEq, Encode, Decode, SpreadAllocate, PackedLayout, SpreadLayout)] #[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))] diff --git a/bucket/ddc_bucket/cluster/messages.rs b/bucket/ddc_bucket/cluster/messages.rs index ccba19e2..df95b355 100644 --- a/bucket/ddc_bucket/cluster/messages.rs +++ b/bucket/ddc_bucket/cluster/messages.rs @@ -539,10 +539,11 @@ impl DdcBucket { // Go through buckets and deduct used resources for &(bucket_id, resources_used) in aggregates_buckets.iter() { - let bucket = self.buckets.get_mut(bucket_id)?; + let mut bucket = self.buckets.get(bucket_id)?; if bucket.resource_consumption_cap <= resources_used { bucket.resource_consumption_cap -= resources_used; + self.buckets.update(bucket_id, &bucket)?; } } diff --git a/bucket/ddc_bucket/cluster/store.rs b/bucket/ddc_bucket/cluster/store.rs index 2a942ab7..de973076 100644 --- a/bucket/ddc_bucket/cluster/store.rs +++ b/bucket/ddc_bucket/cluster/store.rs @@ -1,16 +1,16 @@ //! The store where to create and access Clusters by ID. -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use ink_storage::Mapping; use crate::ddc_bucket::{AccountId, Error::*, Result}; use super::entity::{Cluster, ClusterId, ClusterParams}; #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct ClusterStore { + pub next_cluster_id: u32, pub clusters: Mapping, - pub next_cluster_id: u32 } impl ClusterStore { diff --git a/bucket/ddc_bucket/committer/store.rs b/bucket/ddc_bucket/committer/store.rs index 7216e964..6b2ded3b 100644 --- a/bucket/ddc_bucket/committer/store.rs +++ b/bucket/ddc_bucket/committer/store.rs @@ -1,6 +1,6 @@ use crate::ddc_bucket::{AccountId, Hash, CdnNodeKey}; -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout, PackedLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout, PackedLayout}; use ink_prelude::vec::Vec; use ink_storage::Mapping; @@ -40,7 +40,7 @@ pub struct Commit { } #[derive(Default, Copy, Clone, SpreadAllocate, SpreadLayout, scale::Encode, scale::Decode, Debug)] -#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo, StorageLayout))] +#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo, ink_storage::traits::StorageLayout))] pub struct EraConfig { start: u64, interval: u64, @@ -49,7 +49,7 @@ pub struct EraConfig { } #[derive(Default, SpreadAllocate, SpreadLayout, Debug)] -#[cfg_attr(feature = "std", derive(StorageLayout))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout))] pub struct CommitterStore { operator_id: AccountId, commits: Mapping>, diff --git a/bucket/ddc_bucket/currency.rs b/bucket/ddc_bucket/currency.rs index 880e937c..713a39d5 100644 --- a/bucket/ddc_bucket/currency.rs +++ b/bucket/ddc_bucket/currency.rs @@ -1,6 +1,6 @@ //! The privileged interface for admin tasks. -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use ink_storage::traits::KeyPtr; use crate::ddc_bucket::{Balance, TOKEN}; @@ -10,7 +10,7 @@ pub type USD = Balance; #[derive(SpreadLayout)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct CurrencyConverter(Balance /* how many USD for PRECISION CERE */); const PRECISION: Balance = 10_000_000; diff --git a/bucket/ddc_bucket/network_fee.rs b/bucket/ddc_bucket/network_fee.rs index 25e6b4cf..72de6a0c 100644 --- a/bucket/ddc_bucket/network_fee.rs +++ b/bucket/ddc_bucket/network_fee.rs @@ -1,6 +1,6 @@ //! This module captures fees on behalf of the entire Cere network. -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use scale::{Decode, Encode}; use crate::ddc_bucket::{AccountId, Balance, DdcBucket, Result}; @@ -12,7 +12,7 @@ pub type BasisPoints = Balance; const BP: BasisPoints = 10_000; // 100% #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct NetworkFeeStore( pub FeeConfig, ); @@ -25,7 +25,7 @@ impl NetworkFeeStore { /// The configuration of fees. #[derive(SpreadAllocate, SpreadLayout, Default, Decode, Encode)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug, scale_info::TypeInfo))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug, scale_info::TypeInfo))] pub struct FeeConfig { /// The fee rate from cluster revenues to the overall network. In basis points (1% of 1%). pub network_fee_bp: BasisPoints, diff --git a/bucket/ddc_bucket/node/entity.rs b/bucket/ddc_bucket/node/entity.rs index 29b2943b..0ff3715e 100644 --- a/bucket/ddc_bucket/node/entity.rs +++ b/bucket/ddc_bucket/node/entity.rs @@ -2,9 +2,9 @@ use ink_storage::traits::{SpreadAllocate, PackedLayout, SpreadLayout, PackedAllocate}; use ink_prelude::vec::Vec; +use ink_prelude::string::String; use scale::{Decode, Encode}; -use crate::ddc_bucket::params::store::Params; use crate::ddc_bucket::{AccountId, Balance, VNodeToken, Error::*, Result}; use crate::ddc_bucket::cluster::entity::ClusterId; @@ -13,7 +13,7 @@ use ink_primitives::Key; pub type ProviderId = AccountId; pub type NodeKey = AccountId; -pub type NodeParams = Params; +pub type NodeParams = String; pub type Resource = u32; #[derive(Clone, PartialEq, Encode, Decode, SpreadAllocate, SpreadLayout, PackedLayout)] diff --git a/bucket/ddc_bucket/node/store.rs b/bucket/ddc_bucket/node/store.rs index 0769e998..69495574 100644 --- a/bucket/ddc_bucket/node/store.rs +++ b/bucket/ddc_bucket/node/store.rs @@ -1,6 +1,6 @@ //! The store where to create and access Nodes. -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use ink_prelude::vec::Vec; use ink_storage::Mapping; @@ -10,7 +10,7 @@ use crate::ddc_bucket::{AccountId, Balance, Error::*, Result}; use super::entity::{Node, NodeKey, NodeParams, Resource}; #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct NodeStore { pub nodes: Mapping, // This pagination vector is temporal and must be replaced with an offchain indexer diff --git a/bucket/ddc_bucket/params/messages.rs b/bucket/ddc_bucket/params/messages.rs deleted file mode 100644 index 92b7d5ab..00000000 --- a/bucket/ddc_bucket/params/messages.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! The public interface to change Params. - -use crate::ddc_bucket::{DdcBucket, Result}; - -use super::store::{Params, ParamsId, ParamsStore}; - -impl DdcBucket { - pub fn impl_change_params(store: &mut ParamsStore, params_id: ParamsId, params: Params) -> Result<()> { - store.change(params_id, params)?; - Ok(()) - } -} \ No newline at end of file diff --git a/bucket/ddc_bucket/params/mod.rs b/bucket/ddc_bucket/params/mod.rs deleted file mode 100644 index 94be958f..00000000 --- a/bucket/ddc_bucket/params/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Params management. - -pub mod store; -pub mod messages; diff --git a/bucket/ddc_bucket/params/store.rs b/bucket/ddc_bucket/params/store.rs deleted file mode 100644 index ffe9a314..00000000 --- a/bucket/ddc_bucket/params/store.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! The store where to create and access Nodes. - -use ink_prelude::string::String; -use ink_prelude::vec::Vec; -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; - -use crate::ddc_bucket::{Error::*, Result}; - -pub type ParamsId = u32; -pub type Params = String; - -pub const PARAMS_MAX_LEN: usize = 100_000; - -#[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] -pub struct ParamsStore(pub Vec); - -impl ParamsStore { - pub fn create(&mut self, params: Params) -> Result { - if params.len() > PARAMS_MAX_LEN { - return Err(ParamsSizeExceedsLimit); - } - let params_id: ParamsId = self.0.len().try_into().unwrap(); - self.0.push(params); - Ok(params_id) - } - - pub fn change(&mut self, params_id: ParamsId, params: Params) -> Result { - let current = self.0.get_mut(params_id as usize).ok_or(ParamsDoesNotExist)?; - - if params.len() > PARAMS_MAX_LEN { - return Err(ParamsSizeExceedsLimit); - } - let record_size = if params.len() > current.len() { - params.len() - current.len() - } else { 0 }; - - *current = params; - Ok(record_size) - } - - pub fn get(&self, params_id: ParamsId) -> Result<&Params> { - self.0.get(params_id as usize).ok_or(ParamsDoesNotExist) - } -} diff --git a/bucket/ddc_bucket/perm/store.rs b/bucket/ddc_bucket/perm/store.rs index 69a2edc4..32772d99 100644 --- a/bucket/ddc_bucket/perm/store.rs +++ b/bucket/ddc_bucket/perm/store.rs @@ -2,7 +2,7 @@ use ink_prelude::vec::Vec; use ink_storage::Mapping; -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use scale::Encode; use crate::ddc_bucket::AccountId; @@ -15,7 +15,7 @@ pub type TrustedBy = AccountId; type PermKey = Vec; #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct PermStore(pub Mapping); // TODO: Switch to Mapping (must upgrade ink first). diff --git a/bucket/ddc_bucket/protocol/store.rs b/bucket/ddc_bucket/protocol/store.rs index 9a5ee390..94d42fdd 100644 --- a/bucket/ddc_bucket/protocol/store.rs +++ b/bucket/ddc_bucket/protocol/store.rs @@ -1,4 +1,4 @@ -use ink_storage::traits::{SpreadAllocate, SpreadLayout, PackedLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout, PackedLayout}; use scale::{Decode, Encode}; @@ -6,7 +6,7 @@ use crate::ddc_bucket::{AccountId, Error::*, Result}; use crate::ddc_bucket::cash::{Cash, Payable}; #[derive(Default, Clone, PartialEq, Encode, Decode, SpreadAllocate, SpreadLayout, PackedLayout)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug, scale_info::TypeInfo))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug, scale_info::TypeInfo))] pub struct ProtocolStore { pub admin: AccountId, pub fee_bp: u32, diff --git a/bucket/ddc_bucket/tests/env_utils.rs b/bucket/ddc_bucket/tests/env_utils.rs index 7402cdbf..dd44f128 100644 --- a/bucket/ddc_bucket/tests/env_utils.rs +++ b/bucket/ddc_bucket/tests/env_utils.rs @@ -86,6 +86,7 @@ pub fn print_events(events: &[Event]) { Event::NodeParamsSet(ev) => println!("EVENT {:?}", ev), Event::NodeOwnershipTransferred(ev) => println!("EVENT {:?}", ev), Event::CdnNodeOwnershipTransferred(ev) => println!("EVENT {:?}", ev), + Event::BucketParamsSet(ev) => println!("EVENT {:?}", ev), } } } diff --git a/bucket/ddc_bucket/tests/test_bucket.rs b/bucket/ddc_bucket/tests/test_bucket.rs index 697daffe..a5e5996e 100644 --- a/bucket/ddc_bucket/tests/test_bucket.rs +++ b/bucket/ddc_bucket/tests/test_bucket.rs @@ -116,6 +116,7 @@ fn bucket_create_ok() { // Check the structure of the bucket including the payment flow. let total_rent = ctx.rent_per_month * ctx.cluster_v_nodes.len() as Balance; + let bucket_params = BucketParams::from(""); let expect_bucket = Bucket { owner_id: test_bucket.owner_id, cluster_id: ctx.cluster_id, @@ -126,6 +127,7 @@ fn bucket_create_ok() { resource_reserved: test_bucket.resource, public_availability: false, resource_consumption_cap: 0, + bucket_params: bucket_params }; // Check the status of the bucket. diff --git a/bucket/ddc_bucket/topology/store.rs b/bucket/ddc_bucket/topology/store.rs index 33ad75e5..b9d5ed92 100644 --- a/bucket/ddc_bucket/topology/store.rs +++ b/bucket/ddc_bucket/topology/store.rs @@ -1,7 +1,7 @@ //! The store where to create and access Nodes. use ink_prelude::vec::Vec; use ink_storage::Mapping; -use ink_storage::traits::{SpreadAllocate, SpreadLayout, StorageLayout}; +use ink_storage::traits::{SpreadAllocate, SpreadLayout}; use crate::ddc_bucket::cluster::entity::ClusterId; use crate::ddc_bucket::node::entity::{NodeKey}; @@ -11,7 +11,7 @@ pub type VNodeToken = u64; pub type ClusterVNode = (ClusterId, VNodeToken); #[derive(SpreadAllocate, SpreadLayout, Default)] -#[cfg_attr(feature = "std", derive(StorageLayout, Debug))] +#[cfg_attr(feature = "std", derive(ink_storage::traits::StorageLayout, Debug))] pub struct TopologyStore { // virtual nodes assigned to a physical node v_nodes_map: Mapping>, diff --git a/bucket/lib.rs b/bucket/lib.rs index 187d417c..eea904da 100755 --- a/bucket/lib.rs +++ b/bucket/lib.rs @@ -18,7 +18,6 @@ pub mod ddc_bucket { use committer::store::*; use ink_storage::traits::SpreadAllocate; use node::{entity::*, store::*}; - use params::store::*; use perm::store::*; use topology::store::*; @@ -26,7 +25,6 @@ pub mod ddc_bucket { use crate::ddc_bucket::network_fee::{NetworkFeeStore, FeeConfig}; use crate::ddc_bucket::perm::entity::Permission; - use self::buckets_perms::store::BucketsPermsStore; use self::cdn_node::entity::{CdnNodeInfo, CdnNodeKey, CdnNodeParams}; use self::account::entity::Account; use self::protocol::store::ProtocolStore; @@ -35,7 +33,6 @@ pub mod ddc_bucket { pub mod account; pub mod admin; pub mod bucket; - pub mod buckets_perms; pub mod cash; pub mod cdn_node; pub mod cluster; @@ -44,7 +41,6 @@ pub mod ddc_bucket { pub mod flow; pub mod network_fee; pub mod node; - pub mod params; pub mod perm; pub mod protocol; pub mod schedule; @@ -56,8 +52,6 @@ pub mod ddc_bucket { #[derive(SpreadAllocate, Default)] pub struct DdcBucket { buckets: BucketStore, - buckets_perms: BucketsPermsStore, - bucket_params: ParamsStore, clusters: ClusterStore, cdn_nodes: CdnNodeStore, nodes: NodeStore, @@ -129,6 +123,14 @@ pub mod ddc_bucket { public_availability: bool, } + #[ink(event)] + #[cfg_attr(feature = "std", derive(PartialEq, Debug, scale_info::TypeInfo))] + pub struct BucketParamsSet { + #[ink(topic)] + bucket_id: BucketId, + bucket_params: BucketParams, + } + impl DdcBucket { /// Create a new bucket and return its `bucket_id`. ///