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

Commit

Permalink
Cluster management (#60)
Browse files Browse the repository at this point in the history
* Cluster management for storage nodes
  • Loading branch information
evgeny-s authored Mar 27, 2023
1 parent 3914e62 commit 2d95c29
Show file tree
Hide file tree
Showing 26 changed files with 4,294 additions and 1,664 deletions.
85 changes: 47 additions & 38 deletions .github/workflows/build-and-push.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,52 @@
name: Build and Push
on:
push:
branches:
- not_exists
workflow_dispatch:

env:
ECR_REPOSITORY: crb-smart-contracts
ECR_REGISTRY: 625402836641.dkr.ecr.us-west-2.amazonaws.com
name: Build and save DDC SC binaries
on: [push, release]

jobs:
build-and-push:
runs-on: ubuntu-18.04
build:
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.DEV_NETWORK_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_NETWORK_AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Cargo Cache
uses: actions/cache@v1
- uses: actions/checkout@v3
- name: Install latest nightly
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
path: ~/.cargo
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}
${{ runner.os }}-cargo
- name: Checkout repository
uses: actions/checkout@v1
- name: Build image and push image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
toolchain: nightly
target: x86_64-unknown-linux-gnu
components: rustfmt, clippy

- name: Install dependencies
run: |
rustup target add wasm32-unknown-unknown --toolchain nightly
rustup component add rust-src --toolchain nightly-unknown-linux-gnu
sudo apt-get install binaryen
cargo install cargo-contract --version ^0.14 --force --locked
- name: Run tests
run: |
RUSTFLAGS=-Awarnings cargo test
- name: Build contract
run: |
cargo contract build --release --manifest-path bucket/Cargo.toml
- name: Create names linked to commit
run: |
docker build . -t $ECR_REGISTRY/$ECR_REPOSITORY:$GITHUB_SHA
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$GITHUB_SHA"
docker image tag $ECR_REGISTRY/$ECR_REPOSITORY:$GITHUB_SHA $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$GITHUB_SHA
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
ddc_contract_name=ddc.${GITHUB_SHA:0:7}.contract
echo DDC_CONTRACT_NAME=$ddc_contract_name >> $GITHUB_ENV
ddc_wasm_name=ddc.${GITHUB_SHA:0:7}.wasm
echo DDC_WASM_NAME=$ddc_wasm_name >> $GITHUB_ENV
ddc_metadata_name=ddc.${GITHUB_SHA:0:7}.json
echo DDC_METADATA_NAME=$ddc_metadata_name >> $GITHUB_ENV
- name: Upload contract artifact
uses: actions/[email protected]
with:
name: ${{ env.DDC_CONTRACT_NAME }}
path: ./target/ink/ddc_bucket/ddc_bucket.contract

- name: Upload wasm artifact
uses: actions/[email protected]
with:
name: ${{ env.DDC_WASM_NAME }}
path: ./target/ink/ddc_bucket/ddc_bucket.wasm

- name: Upload metadata artifact
uses: actions/[email protected]
with:
name: ${{ env.DDC_METADATA_NAME }}
path: ./target/ink/ddc_bucket/metadata.json
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/<executable file>",
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
11 changes: 8 additions & 3 deletions bucket/ddc_bucket/admin.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
//! The privileged interface for admin tasks.
use crate::ddc_bucket::{AccountId, Balance, Cash, DdcBucket, Result};
use crate::ddc_bucket::perm::entity::Permission;
use crate::ddc_bucket::{AccountId, Balance, Cash, DdcBucket, Result};

impl DdcBucket {
pub fn message_admin_grant_permission(&mut self, grantee: AccountId, permission: Permission, is_granted: bool) -> Result<()> {
pub fn message_admin_grant_permission(
&mut self,
grantee: AccountId,
permission: Permission,
is_granted: bool,
) -> Result<()> {
self.only_with_permission(Permission::SuperAdmin)?;
self.impl_grant_permission(grantee, permission, is_granted)
}
Expand All @@ -13,4 +18,4 @@ impl DdcBucket {
let admin = self.only_with_permission(Permission::SuperAdmin)?;
Self::send_cash(admin, Cash(amount))
}
}
}
2 changes: 1 addition & 1 deletion bucket/ddc_bucket/cdn_cluster/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl DdcBucket {
};
clusters.push(status);
}
(clusters, self.clusters.0.len())
(clusters, self.clusters.0.len().try_into().unwrap())
}

fn only_cdn_cluster_manager(cluster: &CdnCluster) -> Result<AccountId> {
Expand Down
104 changes: 75 additions & 29 deletions bucket/ddc_bucket/cluster/entity.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
//! The data structure of Clusters.
// use ink_storage::Mapping;
// use ink_prelude::vec::Vec;
use ink_prelude::vec::Vec;
use ink_storage::traits::{PackedLayout, SpreadLayout};
use scale::{Decode, Encode};

use crate::ddc_bucket::{AccountId, Balance, Error::InsufficientResources, NodeId, Result};
use crate::ddc_bucket::cash::Cash;
use crate::ddc_bucket::Error::UnauthorizedClusterManager;
use crate::ddc_bucket::node::entity::{Node, Resource};
use crate::ddc_bucket::node::entity::NodeId;
use crate::ddc_bucket::node::entity::Resource;
use crate::ddc_bucket::params::store::Params;
use crate::ddc_bucket::Error::UnauthorizedClusterManager;
use crate::ddc_bucket::{AccountId, Balance, Error::InsufficientResources, Result};

pub type ClusterId = u32;
pub type ClusterParams = Params;
pub type VNodeIndex = u32;
pub type VNodeId = (ClusterId, VNodeIndex);

#[derive(Clone, PartialEq, Encode, Decode, SpreadLayout, PackedLayout)]
#[derive(Clone, PartialEq, Encode, Decode, PackedLayout, SpreadLayout)]
#[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))]
pub struct Cluster {
pub manager_id: AccountId,
pub vnodes: Vec<NodeId>,
pub resource_per_vnode: Resource,
pub resource_used: Resource,
pub revenues: Cash,
pub node_ids: Vec<NodeId>,
pub v_nodes: Vec<Vec<u64>>,
pub total_rent: Balance,
}

Expand All @@ -35,33 +38,16 @@ pub struct ClusterStatus {
}

impl Cluster {
pub fn new(
manager_id: AccountId,
vnode_count: u32,
nodes: &[(NodeId, &Node)],
) -> Self {
let (vnodes, total_rent) = Self::new_vnodes(vnode_count as usize, nodes);
pub fn new(manager_id: AccountId, v_nodes_arr: &Vec<Vec<u64>>, node_ids: &Vec<NodeId>) -> Self {
Cluster {
manager_id,
vnodes,
resource_per_vnode: 0,
resource_used: 0,
revenues: Cash(0),
total_rent,
}
}

fn new_vnodes(vnode_count: usize, nodes: &[(NodeId, &Node)]) -> (Vec<NodeId>, Balance) {
let node_count = nodes.len();
let mut vnode_ids = Vec::with_capacity(vnode_count);
let mut total_rent = 0;
for i in 0..vnode_count {
let (node_id, node) = &nodes[i % node_count];
vnode_ids.push(*node_id);
total_rent += node.rent_per_month;
v_nodes: v_nodes_arr.clone(),
node_ids: node_ids.clone(),
total_rent: 0,
}
// TODO: consider using the max rent instead of average rent.
(vnode_ids, total_rent)
}

pub fn get_rent(&self, resource: Resource) -> Balance {
Expand All @@ -81,7 +67,67 @@ impl Cluster {
Ok(())
}

// v_nodes should be sorted
pub fn replace_v_node(&mut self, v_nodes: Vec<u64>, node_id: NodeId) {
let old_v_nodes = &self.v_nodes;
let old_node_ids = &self.node_ids;

let mut new_v_nodes = Vec::<Vec<u64>>::new();
let mut new_node_ids = Vec::<NodeId>::new();

let mut new_v_nodes_idx = 0;
let mut v_nodes_for_new_node = Vec::<u64>::new();

for wrapper_idx in 0..old_v_nodes.len() {
let mut v_nodes_wrapper = Vec::<u64>::new();
for idx in 0..old_v_nodes.get(wrapper_idx).unwrap().len() {
let new_v_node = match v_nodes.get(new_v_nodes_idx) {
Some(v) => *v,
None => 0,
};

if old_v_nodes
.get(wrapper_idx)
.unwrap()
.get(idx)
.unwrap()
.clone()
== new_v_node
{
v_nodes_for_new_node.push(new_v_node);
new_v_nodes_idx += 1;
} else {
v_nodes_wrapper.push(
old_v_nodes
.get(wrapper_idx)
.unwrap()
.get(idx)
.unwrap()
.clone(),
);
}
}

new_v_nodes.push(v_nodes_wrapper);
new_node_ids.push(*old_node_ids.get(wrapper_idx).unwrap());
}

new_v_nodes.push(v_nodes_for_new_node);
new_node_ids.push(node_id);

self.v_nodes = new_v_nodes;
self.node_ids = new_node_ids;
}

pub fn only_manager(&self, caller: AccountId) -> Result<()> {
if self.manager_id == caller { Ok(()) } else { Err(UnauthorizedClusterManager) }
if self.manager_id == caller {
Ok(())
} else {
Err(UnauthorizedClusterManager)
}
}
}

pub fn change_rent(&mut self, rent: Balance) {
self.total_rent = rent;
}
}
Loading

0 comments on commit 2d95c29

Please sign in to comment.