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

Commit

Permalink
Merge pull request #59 from Cerebellum-Network/feature/test-distribut…
Browse files Browse the repository at this point in the history
…ion-payments

Feature/test distribution payments
- automate validated commits
- create protocol module 
- create logics for protocol fees
  • Loading branch information
Raid5594 authored Dec 13, 2022
2 parents d3b4251 + 3f95dd2 commit 9821b86
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 46 deletions.
8 changes: 4 additions & 4 deletions bucket/ddc_bucket/cash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! These data structures facilitate the correctness of money-related calculations using the Rust type system.

use ink_storage::traits::{PackedLayout, SpreadLayout};
use ink_storage::traits;
use scale::{Decode, Encode};

use crate::ddc_bucket::{Balance, Result};
Expand All @@ -11,14 +11,14 @@ use crate::ddc_bucket::Error::InsufficientBalance;
// TODO: remove Clone.
/// 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(Debug))]
#[derive(Clone, Copy, PartialEq, Encode, Decode, traits::SpreadLayout, traits::PackedLayout)]
#[cfg_attr(feature = "std", derive(traits::StorageLayout, Debug))]
pub struct Cash(pub Balance);

/// Payable represents some value that was credited to someone, and that must be paid by someone.
/// Payable must be covered by Cash at all times to guarantee the balance of the contract.
#[must_use]
#[derive(PartialEq, Encode, Decode, SpreadLayout, PackedLayout)]
#[derive(PartialEq, Encode, Decode, traits::SpreadLayout, traits::PackedLayout)]
#[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))]
pub struct Payable(pub Balance);

Expand Down
18 changes: 14 additions & 4 deletions bucket/ddc_bucket/cdn_cluster/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl DdcBucket {
}

// First payment is for aggregate consumption for account, second is the aggregate payment for the node (u32 for ids)
pub fn message_cdn_cluster_put_revenue(&mut self, cluster_id: ClusterId, aggregates_accounts: Vec<(AccountId, u128)>, aggregates_nodes: Vec<(u32, u128)>, aggregates_buckets: Vec<(BucketId, Resource)>) -> Result<()> {
pub fn message_cdn_cluster_put_revenue(&mut self, cluster_id: ClusterId, aggregates_accounts: Vec<(AccountId, u128)>, aggregates_nodes: Vec<(u32, u128)>, aggregates_buckets: Vec<(BucketId, Resource)>, era: u64) -> Result<()> {
let cluster = self.cdn_clusters.get_mut(cluster_id)?;
// Self::only_cdn_cluster_manager(cluster)?;

Expand All @@ -81,14 +81,24 @@ impl DdcBucket {
}

let conv = &self.accounts.1;
let committer = &mut self.committer_store;

for &(node_id, resources_used) in aggregates_nodes.iter() {
let node = self.cdn_nodes.get_mut(node_id)?;

let protocol_fee = self.protocol_store.get_fee_bp();
let protocol = &mut self.protocol_store;

let payment = conv.to_cere (resources_used as Balance * cluster.usd_per_gb / KB_PER_GB );

node.put_payment(payment);
cluster_payment += payment;
// let protocol_payment = payment * protocol_fee as u128/ 10_000;
let node_payment = payment * (10_000 - protocol_fee) as u128 / 10_000;
let protocol_payment = payment - node_payment;

node.put_payment(node_payment);
protocol.put_revenues(Cash(protocol_payment));

committer.set_validated_commit(node_id, era).unwrap();
cluster_payment += node_payment;
}
// Add check that two payments should equal?

Expand Down
9 changes: 1 addition & 8 deletions bucket/ddc_bucket/committer/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ impl DdcBucket {
self.committer_store.get_commit(cdn_owner)
}

pub fn message_set_validated_commit(&mut self, node: AccountId, era: u64) -> Result<()> {
match self.committer_store.set_validated_commit(node, era) {
Err(_e) => panic!("Setting validated commit failed"),
Ok(_v) => Ok(()),
}
}

pub fn message_get_validated_commit(&self, node: AccountId) -> EraAndTimestamp {
pub fn message_get_validated_commit(&self, node: NodeId) -> EraAndTimestamp {
self.committer_store.get_validate_commit(node)
}

Expand Down
10 changes: 5 additions & 5 deletions bucket/ddc_bucket/committer/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct EraStatus {
#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))]
pub struct Commit {
hash: Hash,
total: u128,
total_logs: u128,
from_timestamp: u64,
to_timestamp: u64,
}
Expand All @@ -57,7 +57,7 @@ pub struct EraConfig {
pub struct CommitterStore {
operator_id: AccountId,
commits: StorageHashMap<AccountId, Vec<(NodeId, Commit)>>,
validated_commits: StorageHashMap<AccountId, EraAndTimestamp>,
validated_commits: StorageHashMap<NodeId, EraAndTimestamp>,
era_settings: EraConfig
}

Expand Down Expand Up @@ -101,14 +101,14 @@ impl CommitterStore {
}

// Set the last validated commit per CDN node
pub fn set_validated_commit(&mut self, node: AccountId, era: u64) -> Result<()> {
pub fn set_validated_commit(&mut self, node: NodeId, era: u64) -> Result<()> {
let prev_era_to_timestamp = self.era_settings.start + self.era_settings.interval * (era + 1);
self.validated_commits.insert(node, (era, prev_era_to_timestamp));
Ok(())
}

// Get the last era & timestamp validated per CDN node
pub fn get_validate_commit(&self, node: AccountId) -> EraAndTimestamp {
pub fn get_validate_commit(&self, node: NodeId) -> EraAndTimestamp {
*self.validated_commits.get(&node).unwrap_or(&(0,0))
}

Expand All @@ -132,7 +132,7 @@ impl CommitterStore {

let current_phase = if elapsed_time_within_interval < self.era_settings.commit_duration {
Phase::Commit
} else if elapsed_time_within_interval < self.era_settings.validation_duration {
} else if elapsed_time_within_interval < self.era_settings.validation_duration + self.era_settings.commit_duration {
Phase::Valiadation
} else {
Phase::Payout
Expand Down
35 changes: 35 additions & 0 deletions bucket/ddc_bucket/protocol/messages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! The public interface to manage Protocol (fees included).

use crate::ddc_bucket::{DdcBucket, Result};
use crate::ddc_bucket::cash::{Cash, Payable};

impl DdcBucket {
pub fn message_get_fee_bp(&self) -> u32 {
self.protocol_store.get_fee_bp()
}

pub fn message_set_fee_bp(&mut self, fee_bp: u32) -> Result<()> {
match self.protocol_store.set_fee_bp(fee_bp) {
Err(_e) => panic!("Setting fee failed"),
Ok(_v) => Ok(()),
}
}

pub fn message_get_fee_revenues(&self) -> Cash {
self.protocol_store.get_fee_revenues()
}

pub fn message_put_fee_revenues(&mut self, amount: Cash) -> Result<()> {
self.protocol_store.put_revenues(amount);

Ok(())
}

pub fn message_withdraw_revenues(&mut self, amount: u128) -> Result<()> {
self.protocol_store.withdraw_revenues(Payable(amount))?;

Self::send_cash(self.protocol_store.admin, Cash(amount))?;

Ok(())
}
}
4 changes: 4 additions & 0 deletions bucket/ddc_bucket/protocol/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Protocol Management (Fees, ...)

pub mod store;
pub mod messages;
52 changes: 52 additions & 0 deletions bucket/ddc_bucket/protocol/store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use ink_storage::traits;

use scale::{Decode, Encode};

use crate::ddc_bucket::{AccountId, Error::*, Result};
use crate::ddc_bucket::cash::{Cash, Payable};

#[derive(Clone, PartialEq, Encode, Decode, traits::SpreadLayout, traits::PackedLayout)]
#[cfg_attr(feature = "std", derive(traits::StorageLayout, Debug, scale_info::TypeInfo))]
pub struct ProtocolStore {
pub admin: AccountId,
pub fee_bp: u32,
pub revenues: Cash,
}

impl ProtocolStore {
pub fn new(
admin: AccountId,
fee_bp: u32,
) -> Self {
ProtocolStore {
admin,
fee_bp,
revenues: Cash(0),
}
}

pub fn get_fee_bp(&self) -> u32 {
self.fee_bp
}

pub fn set_fee_bp(&mut self, fee_bp: u32) -> Result<()> {
self.fee_bp = fee_bp;
Ok(())
}

pub fn get_fee_revenues(&self) -> Cash {
self.revenues
}

pub fn put_revenues(&mut self, amount: Cash) {
self.revenues.increase(amount);
}

pub fn withdraw_revenues(&mut self, amount: Payable) -> Result<()> {
if amount.peek() > self.revenues.peek() {
return Err(InsufficientBalance);
}
self.revenues.pay_unchecked(amount);
Ok(())
}
}
51 changes: 48 additions & 3 deletions bucket/ddc_bucket/tests/test_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,16 +458,62 @@ fn cdn_cluster_payment_works() {
ctx.contract.account_bond(5 * TOKEN);
pop_caller();

push_caller(ctx.provider_id0);
ctx.contract.set_fee_bp(1_000);
pop_caller();


let mut account = ctx.contract.accounts.get(&ctx.provider_id0).unwrap();
println!("{:?}", account);

ctx.contract.cdn_cluster_put_revenue(ctx.cluster_id,vec![(ctx.provider_id0, 1000), (ctx.provider_id0, 541643)], vec![(ctx.node_id0, 1000), (ctx.node_id1, 541643)], vec![]);
ctx.contract.cdn_cluster_put_revenue(ctx.cluster_id,vec![(ctx.provider_id0, 1000), (ctx.provider_id0, 541643)], vec![(ctx.node_id0, 1000), (ctx.node_id1, 541643)], vec![], 5);
account = ctx.contract.accounts.get(&ctx.provider_id0).unwrap();
println!("{:?}", account);

let cdn_cluster_list_one = ctx.contract.cdn_cluster_list(0, 10, None);
print!("Cluster list one {:?}", cdn_cluster_list_one);
let node0 = ctx.contract.cdn_nodes.get(ctx.node_id0).unwrap();
let node1 = ctx.contract.cdn_nodes.get(ctx.node_id1).unwrap();

println!("Node 1 {:?}", node0);
println!("Node 2 {:?}", node1);
// let cdn_cluster0 = ctx.contract.cdn_clusters.get(ctx.cluster_id);
// print!("{:?}", cdn_cluster0);
// let cdn_cluster_list = ctx.contract.cdn_cluster_list(0, 10, None);
// print!("{:?}", cdn_cluster0);
// print!("{:?}", cdn_cluster_list);

let validated_commit_node0 = ctx.contract.get_validated_commit(ctx.node_id0);
print!("Validated commit {:?}", validated_commit_node0);

let fee = ctx.contract.get_fee_bp();
print!("Protocol fee in basis points {:?}", fee);

let protocol_revenues = ctx.contract.get_protocol_revenues();
print!("Protocol revenues are {:?}", protocol_revenues);

push_caller(ctx.provider_id0);
ctx.contract.cdn_cluster_distribute_revenues(0);
pop_caller();

let node0 = ctx.contract.cdn_nodes.get(ctx.node_id0).unwrap();
let node1 = ctx.contract.cdn_nodes.get(ctx.node_id1).unwrap();
println!("{:?}", account);
println!("{:?}", node0);
println!("{:?}", node1);

let cdn_cluster_list = ctx.contract.cdn_cluster_list(0, 10, None);
print!("{:?}", cdn_cluster_list);


account = ctx.contract.accounts.get(&ctx.provider_id0).unwrap();
// let node0 = ctx.contract.cdn_nodes.get(ctx.node_id0).unwrap();
// let node1 = ctx.contract.cdn_nodes.get(ctx.node_id1).unwrap();
println!("{:?}", account);
// let account1 = ctx.contract.accounts.get(&ctx.provider_id1).unwrap();
// println!("{:?}", account1);
// let account_balance = ink_env::balance(&ctx.provider_id0);
// println!("{:?}", account_balance);

}

fn bucket_settle_payment(ctx: &mut TestCluster, test_bucket: &TestBucket) {
Expand All @@ -480,7 +526,6 @@ fn bucket_settle_payment(ctx: &mut TestCluster, test_bucket: &TestBucket) {
pop_caller();
}


#[ink::test]
fn bucket_pays_cluster() {
let ctx = &mut new_cluster();
Expand Down
Loading

0 comments on commit 9821b86

Please sign in to comment.