Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
fix(bucket): bucket resource allocation fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
yahortsaryk committed Jul 3, 2023
1 parent bd1ed1b commit 062e106
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 26 deletions.
23 changes: 18 additions & 5 deletions bucket/ddc_bucket/bucket/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use ink_lang::codegen::{EmitEvent, StaticEnv};
use ink_prelude::vec::Vec;

use crate::ddc_bucket::{AccountId, BucketAllocated, BucketCreated, BucketSettlePayment, BucketAvailabilityUpdated, BucketParamsSet, DdcBucket, Result};
use crate::ddc_bucket::{AccountId, Balance, BucketAllocated, BucketCreated, BucketSettlePayment, BucketAvailabilityUpdated, BucketParamsSet, DdcBucket, Result, Error::*};
use crate::ddc_bucket::cluster::entity::{Cluster, ClusterId};
use crate::ddc_bucket::node::entity::Resource;

Expand Down Expand Up @@ -31,22 +31,31 @@ impl DdcBucket {
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)?;
// todo: fix resource allocation
cluster.take_resource(resource)?;

let cluster_v_nodes = self.get_v_nodes_by_cluster(bucket.cluster_id);
let cluster_v_nodes_len: u32 = cluster_v_nodes.len().try_into().unwrap();
let max_cluster_resource = cluster_v_nodes_len * cluster.resource_per_v_node;

if cluster.resource_used + resource > max_cluster_resource {
return Err(InsufficientClusterResources);
}

cluster.take_resource(resource);
self.clusters.update(bucket.cluster_id, &cluster)?;
bucket.put_resource(resource);

// Start the payment flow to the cluster.
let rent = cluster.get_rent(resource);
let extra_rate = cluster.total_rent * resource as Balance;
let now_ms = Self::env().block_timestamp();

self.accounts.increase_flow(now_ms, rent, &mut bucket.flow)?;
self.accounts.increase_flow(now_ms, extra_rate, &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 mut bucket = self.buckets.get(bucket_id)?;

Expand All @@ -73,11 +82,13 @@ impl DdcBucket {
Ok(())
}


pub fn message_bucket_get(&self, bucket_id: BucketId) -> Result<BucketStatus> {
let bucket = self.buckets.get(bucket_id)?;
self.bucket_calculate_status(bucket_id, bucket)
}


pub fn message_bucket_list(&self, offset: u32, limit: u32, filter_owner_id: Option<AccountId>) -> (Vec<BucketStatus>, u32) {
let mut bucket_statuses = Vec::with_capacity(limit as usize);
for bucket_id in offset..offset + limit {
Expand All @@ -101,6 +112,7 @@ impl DdcBucket {
(bucket_statuses, self.buckets.next_bucket_id)
}


pub fn message_bucket_list_for_account(&self, owner_id: AccountId) -> Vec<Bucket> {
let mut result : Vec<Bucket> = Vec::new();

Expand All @@ -115,6 +127,7 @@ impl DdcBucket {
result
}


pub fn bucket_calculate_status(&self, bucket_id: BucketId, bucket: Bucket) -> Result<BucketStatus> {
let mut writer_ids = self.buckets.get_bucket_readers(bucket_id);
writer_ids.push(bucket.owner_id);
Expand Down
20 changes: 9 additions & 11 deletions bucket/ddc_bucket/cluster/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,20 @@ impl Cluster {
Ok(())
}

pub fn get_rent(&self, resource: Resource) -> Balance {
let rent = self.total_rent * resource as Balance;
rent
pub fn increase_rent(&mut self, amount: Balance) {
self.total_rent += amount;
}


pub fn decrease_rent(&mut self, amount: Balance) {
self.total_rent -= amount;
}

pub fn set_resource_per_v_node(&mut self, resource_per_v_node: Resource) {
self.resource_per_v_node = resource_per_v_node;
}

pub fn take_resource(&mut self, amount: Resource) -> Result<()> {
let used = self.resource_used + amount;
if used > self.resource_per_v_node {
return Err(InsufficientResources);
}
self.resource_used = used;
Ok(())
pub fn take_resource(&mut self, amount: Resource) {
self.resource_used = self.resource_used + amount;
}

pub fn cdn_get_revenue_cere(&self) -> Cash {
Expand Down
16 changes: 11 additions & 5 deletions bucket/ddc_bucket/cluster/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl DdcBucket {
cluster.add_node(node_key)?;
for _v_node in &v_nodes {
node.reserve_resource(cluster.resource_per_v_node)?;
cluster.total_rent += node.rent_v_node_per_month;
cluster.increase_rent(node.rent_v_node_per_month);
}

self.nodes.update(node_key, &node)?;
Expand Down Expand Up @@ -99,15 +99,14 @@ impl DdcBucket {
&& !node.only_provider(caller).is_ok() {
return Err(OnlyClusterManagerOrNodeProvider);
}

node.only_with_cluster(cluster_id)?;

node.unset_cluster();
cluster.remove_node(node_key);
let v_nodes = self.topology.get_v_nodes_by_node(node_key);
for _v_node in &v_nodes {
node.release_resource(cluster.resource_per_v_node);
cluster.total_rent -= node.rent_v_node_per_month;
cluster.decrease_rent(node.rent_v_node_per_month);
}

self.nodes.update(node_key, &node)?;
Expand Down Expand Up @@ -189,14 +188,14 @@ impl DdcBucket {

for _i in 0..new_v_nodes.len() - old_v_nodes.len() {
node.reserve_resource(cluster.resource_per_v_node)?;
cluster.total_rent += node.rent_v_node_per_month;
cluster.increase_rent(node.rent_v_node_per_month);
}

} else if new_v_nodes.len() < old_v_nodes.len() {

for _i in 0..old_v_nodes.len() - new_v_nodes.len() {
node.release_resource(cluster.resource_per_v_node);
cluster.total_rent -= node.rent_v_node_per_month;
cluster.decrease_rent(node.rent_v_node_per_month);
}
}

Expand Down Expand Up @@ -418,6 +417,13 @@ impl DdcBucket {

cluster.set_resource_per_v_node(new_resource_per_v_node);
let cluster_v_nodes = self.topology.get_v_nodes_by_cluster(cluster_id);
let cluster_v_nodes_len: u32 = cluster_v_nodes.len().try_into().unwrap();

let new_max_cluster_resource = cluster_v_nodes_len * new_resource_per_v_node;
if cluster.resource_used > new_max_cluster_resource {
return Err(InsufficientClusterResources);
}

for v_node in cluster_v_nodes {
let node_key = self.topology.get_node_by_v_node(cluster_id, v_node)?;
let mut node = self.nodes.get(node_key)?;
Expand Down
2 changes: 1 addition & 1 deletion bucket/ddc_bucket/node/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl Node {
self.free_resource -= amount;
Ok(())
} else {
Err(InsufficientResources)
Err(InsufficientNodeResources)
}
}

Expand Down
10 changes: 6 additions & 4 deletions bucket/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ pub mod ddc_bucket {
/// * `NodeIsAddedToCluster(ClusterId)` error if the adding Storage node is already added to this or another cluster.
/// * `AtLeastOneVNodeHasToBeAssigned(ClusterId, NodeKey)` error if there is a Storage node without any virtual nodes in the cluster.
/// * `VNodesSizeExceedsLimit` error if virtual nodes length exceeds storage capacity.
/// * `InsufficientResources` - error if there is not enough resources in a physical node.
/// * `InsufficientNodeResources` - error if there is not enough resources in a physical node.
#[ink(message, payable)]
pub fn cluster_add_node(
&mut self,
Expand Down Expand Up @@ -574,7 +574,7 @@ pub mod ddc_bucket {
/// * `NodeIsAddedToCluster(ClusterId)` error if the adding Storage node is already added to this or another cluster.
/// * `AtLeastOneVNodeHasToBeAssigned(ClusterId, NodeKey)` error if there is a Storage node without any virtual nodes in the cluster.
/// * `VNodesSizeExceedsLimit` error if virtual nodes length exceeds storage capacity.
/// * `InsufficientResources` - error if there is not enough resources in a physical node.
/// * `InsufficientNodeResources` - error if there is not enough resources in a physical node.
#[ink(message)]
pub fn cluster_reset_node(
&mut self,
Expand Down Expand Up @@ -816,7 +816,8 @@ pub mod ddc_bucket {
/// * `OnlyClusterManager` error if the caller is not the cluster manager.
/// * `NodeDoesNotExist` error if the new Storage node does not exist.
/// * `VNodeIsNotAssignedToNode(ClusterId, VNodeToken)` error if the there is some virtual node that is being reasigned, but this virtual node is not assigned to any physical node.
/// * `InsufficientResources` - error if there is not enough resources in a physical node.
/// * `InsufficientClusterResources` - error if there is not enough resources in the cluster.
/// * `InsufficientNodeResources` - error if there is not enough resources in a physical node.
#[ink(message)]
pub fn cluster_set_resource_per_v_node(
&mut self,
Expand Down Expand Up @@ -1765,7 +1766,8 @@ pub mod ddc_bucket {
BondingPeriodNotFinished,
TransferFailed,
InsufficientBalance,
InsufficientResources,
InsufficientNodeResources,
InsufficientClusterResources,
EraSettingFailed
}

Expand Down

0 comments on commit 062e106

Please sign in to comment.