This repository has been archived by the owner on May 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from Cerebellum-Network/splitfile
Split file
- Loading branch information
Showing
23 changed files
with
768 additions
and
509 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use ink_storage::traits::{PackedLayout, SpreadLayout}; | ||
use scale::{Decode, Encode}; | ||
|
||
use crate::ddc_bucket::{ | ||
Balance, cash::{Cash, Payable}, | ||
Error::*, Result, | ||
schedule::Schedule, | ||
}; | ||
|
||
#[derive(PartialEq, Encode, Decode, SpreadLayout, PackedLayout)] | ||
#[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))] | ||
pub struct Account { | ||
pub deposit: Cash, | ||
pub payable_locked: Balance, | ||
pub payable_schedule: Schedule, | ||
} | ||
|
||
impl Account { | ||
pub fn new() -> Account { | ||
Account { | ||
deposit: Cash(0), | ||
payable_locked: 0, | ||
payable_schedule: Schedule::empty(), | ||
} | ||
} | ||
|
||
pub fn deposit(&mut self, cash: Cash) { | ||
self.deposit.increase(cash); | ||
} | ||
|
||
pub fn withdraw(&mut self, time_ms: u64, payable: Payable) -> Result<()> { | ||
if self.get_withdrawable(time_ms) >= payable.peek() { | ||
self.deposit.pay_unchecked(payable); | ||
Ok(()) | ||
} else { | ||
Err(InsufficientBalance) | ||
} | ||
} | ||
|
||
pub fn get_withdrawable(&self, time_ms: u64) -> Balance { | ||
let deposit = self.deposit.peek(); | ||
let consumed = self.payable_locked + self.payable_schedule.value_at_time(time_ms); | ||
if deposit >= consumed { | ||
deposit - consumed | ||
} else { | ||
0 | ||
} | ||
} | ||
|
||
pub fn lock_schedule(&mut self, payable_schedule: Schedule) { | ||
let more_locked = self.payable_schedule.take_value_then_add_rate(payable_schedule); | ||
self.payable_locked += more_locked; | ||
} | ||
|
||
pub fn schedule_covered_until(&self) -> u64 { | ||
self.payable_schedule.time_of_value(self.deposit.peek()) | ||
} | ||
|
||
pub fn pay_scheduled(&mut self, now_ms: u64, payable: Payable) -> Result<()> { | ||
self.unlock_scheduled_amount(now_ms, payable.peek()); | ||
self.pay(payable) | ||
} | ||
|
||
fn pay(&mut self, payable: Payable) -> Result<()> { | ||
if self.deposit.peek() >= payable.peek() { | ||
self.deposit.pay_unchecked(payable); | ||
Ok(()) | ||
} else { | ||
Err(InsufficientBalance) | ||
} | ||
} | ||
|
||
fn unlock_scheduled_amount(&mut self, now_ms: u64, unlocked: Balance) { | ||
self.payable_locked = self.payable_locked | ||
+ self.payable_schedule.take_value_at_time(now_ms) | ||
- unlocked; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod entity; | ||
pub mod store; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
use ink_storage::{ | ||
collections::{HashMap, hashmap::Entry::*}, | ||
traits, | ||
}; | ||
|
||
use crate::ddc_bucket::{ | ||
AccountId, Balance, cash::Cash, Error::*, | ||
Result, | ||
}; | ||
|
||
use super::entity::Account; | ||
|
||
#[derive(traits::SpreadLayout, Default)] | ||
#[cfg_attr(feature = "std", derive(traits::StorageLayout, Debug))] | ||
pub struct AccountStore(pub HashMap<AccountId, Account>); | ||
|
||
impl AccountStore { | ||
pub fn deposit(&mut self, to: AccountId, cash: Cash) { | ||
match self.0.entry(to) { | ||
Vacant(e) => { | ||
let mut account = Account::new(); | ||
account.deposit(cash); | ||
e.insert(account); | ||
} | ||
Occupied(mut e) => { | ||
let account = e.get_mut(); | ||
account.deposit(cash); | ||
} | ||
}; | ||
} | ||
|
||
pub fn balance(&self, account_id: &AccountId) -> Balance { | ||
match self.0.get(account_id) { | ||
None => 0, | ||
Some(account) => account.deposit.peek(), | ||
} | ||
} | ||
|
||
pub fn get(&self, account_id: &AccountId) -> Result<&Account> { | ||
self.0.get(account_id).ok_or(AccountDoesNotExist) | ||
} | ||
|
||
pub fn get_mut(&mut self, account_id: &AccountId) -> Result<&mut Account> { | ||
self.0.get_mut(account_id).ok_or(AccountDoesNotExist) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use ink_lang::{EmitEvent, StaticEnv}; | ||
|
||
use crate::ddc_bucket::{AccountId, Balance, Cash, DdcBucket, Deposit, FlowId, InsufficientBalance, Payable, Result, Schedule}; | ||
|
||
impl DdcBucket { | ||
pub fn message_deposit(&mut self) -> Result<()> { | ||
// Receive the payable value. | ||
let cash = Self::receive_cash(); | ||
let value = cash.peek(); | ||
let account_id = Self::env().caller(); | ||
|
||
self.accounts.deposit(account_id, cash); | ||
Self::env().emit_event(Deposit { account_id, value }); | ||
Ok(()) | ||
} | ||
|
||
pub fn billing_withdraw(&mut self, from: AccountId, payable: Payable) -> Result<()> { | ||
let account = self.accounts.0.get_mut(&from) | ||
.ok_or(InsufficientBalance)?; | ||
|
||
let time_ms = Self::env().block_timestamp(); | ||
account.withdraw(time_ms, payable)?; | ||
Ok(()) | ||
} | ||
|
||
pub fn billing_get_net(&self, from: AccountId) -> Balance { | ||
match self.accounts.0.get(&from) { | ||
None => 0, | ||
Some(account) => { | ||
let time_ms = Self::env().block_timestamp(); | ||
account.get_withdrawable(time_ms) | ||
} | ||
} | ||
} | ||
|
||
pub fn billing_transfer(&mut self, from: AccountId, to: AccountId, amount: Balance) -> Result<()> { | ||
let (payable, cash) = Cash::borrow_payable_cash(amount); | ||
self.billing_withdraw(from, payable)?; | ||
self.accounts.deposit(to, cash); | ||
Ok(()) | ||
} | ||
|
||
pub fn billing_start_flow(&mut self, from: AccountId, rate: Balance) -> Result<FlowId> { | ||
let start_ms = Self::env().block_timestamp(); | ||
let cash_schedule = Schedule::new(start_ms, rate); | ||
let payable_schedule = cash_schedule.clone(); | ||
|
||
let from_account = self.accounts.get_mut(&from)?; | ||
from_account.lock_schedule(payable_schedule); | ||
|
||
let flow_id = self.flows.create(from, cash_schedule); | ||
Ok(flow_id) | ||
} | ||
|
||
pub fn billing_flow_covered_until(&self, flow_id: FlowId) -> Result<u64> { | ||
let flow = self.flows.get(flow_id)?; | ||
let account = self.accounts.get(&flow.from)?; | ||
Ok(account.schedule_covered_until()) | ||
} | ||
|
||
pub fn billing_settle_flow(&mut self, flow_id: FlowId) -> Result<Cash> { | ||
let now_ms = Self::env().block_timestamp(); | ||
|
||
let flow = self.flows.get_mut(flow_id)?; | ||
let flowed_amount = flow.schedule.take_value_at_time(now_ms); | ||
let (payable, cash) = Cash::borrow_payable_cash(flowed_amount); | ||
|
||
let account = self.accounts.get_mut(&flow.from)?; | ||
account.pay_scheduled(now_ms, payable)?; | ||
Ok(cash) | ||
} | ||
|
||
pub fn receive_cash() -> Cash { | ||
Cash(Self::env().transferred_balance()) | ||
} | ||
|
||
pub fn send_cash(destination: AccountId, cash: Cash) -> Result<()> { | ||
match Self::env().transfer(destination, cash.consume()) { | ||
Err(_e) => panic!("Transfer failed"), // Err(Error::TransferFailed), | ||
Ok(_v) => Ok(()), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use ink_prelude::{ | ||
string::String, | ||
vec::Vec, | ||
}; | ||
use ink_storage::traits::{PackedLayout, SpreadLayout}; | ||
use scale::{Decode, Encode}; | ||
|
||
use crate::ddc_bucket::{ | ||
AccountId, deal::entity::{DealId, DealStatus}, Error::*, | ||
Result, | ||
}; | ||
|
||
pub type BucketId = u32; | ||
pub type BucketParams = String; | ||
|
||
#[derive(Clone, PartialEq, Encode, Decode, SpreadLayout, PackedLayout)] | ||
#[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))] | ||
pub struct Bucket { | ||
pub owner_id: AccountId, | ||
pub deal_ids: Vec<DealId>, | ||
pub bucket_params: BucketParams, | ||
} | ||
|
||
#[derive(Clone, PartialEq, Encode, Decode)] | ||
#[cfg_attr(feature = "std", derive(Debug, scale_info::TypeInfo))] | ||
pub struct BucketStatus { | ||
pub bucket_id: BucketId, | ||
pub bucket: Bucket, | ||
pub writer_ids: Vec<AccountId>, | ||
pub deal_statuses: Vec<DealStatus>, | ||
} | ||
|
||
impl Bucket { | ||
pub fn only_owner(&self, caller: AccountId) -> Result<()> { | ||
if self.owner_id == caller { Ok(()) } else { Err(UnauthorizedOwner) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use ink_lang::{EmitEvent, StaticEnv}; | ||
use ink_prelude::{vec, vec::Vec}; | ||
|
||
use crate::ddc_bucket::{AccountId, BucketCreated, DdcBucket, DealCreated, DealId, DealParams, Result, ServiceId}; | ||
|
||
use super::entity::{Bucket, BucketId, BucketParams, BucketStatus}; | ||
|
||
impl DdcBucket { | ||
pub fn message_bucket_create(&mut self, bucket_params: BucketParams) -> Result<BucketId> { | ||
let owner_id = Self::env().caller(); | ||
let bucket_id = self.buckets.create(owner_id, bucket_params); | ||
Self::env().emit_event(BucketCreated { bucket_id, owner_id }); | ||
Ok(bucket_id) | ||
} | ||
|
||
pub fn message_bucket_add_deal(&mut self, bucket_id: BucketId, service_id: ServiceId, deal_params: DealParams) -> Result<DealId> { | ||
// Receive the payable value. | ||
self.deposit()?; | ||
let owner_id = Self::env().caller(); | ||
|
||
let deal_id = self.deal_create(service_id, deal_params)?; | ||
|
||
let bucket = self.buckets.get_mut(bucket_id)?; | ||
bucket.only_owner(owner_id)?; | ||
bucket.deal_ids.push(deal_id); | ||
|
||
Self::env().emit_event(DealCreated { deal_id, bucket_id, service_id }); | ||
Ok(deal_id) | ||
} | ||
|
||
pub fn message_bucket_list_statuses(&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 { | ||
let bucket = match self.buckets.0.get(bucket_id) { | ||
None => break, // No more buckets, stop. | ||
Some(bucket) => bucket, | ||
}; | ||
// Apply the filter if given. | ||
if let Some(owner_id) = filter_owner_id { | ||
if owner_id != bucket.owner_id { | ||
continue; // Skip non-matches. | ||
} | ||
} | ||
// Collect all the details of the bucket. | ||
match self.bucket_collect_status(bucket_id, bucket.clone()) { | ||
Err(_) => continue, // Skip on unexpected error. | ||
Ok(status) => | ||
bucket_statuses.push(status), | ||
}; | ||
} | ||
(bucket_statuses, self.buckets.0.len()) | ||
} | ||
|
||
pub fn message_bucket_get_status(&self, bucket_id: BucketId) -> Result<BucketStatus> { | ||
let bucket = self.bucket_get(bucket_id)?; | ||
self.bucket_collect_status(bucket_id, bucket) | ||
} | ||
|
||
pub fn bucket_collect_status(&self, bucket_id: BucketId, bucket: Bucket) -> Result<BucketStatus> { | ||
let writer_ids = vec![bucket.owner_id]; | ||
|
||
let mut deal_statuses = Vec::with_capacity(bucket.deal_ids.len()); | ||
for deal_id in bucket.deal_ids.iter() { | ||
deal_statuses.push(self.deal_get_status(*deal_id)?); | ||
} | ||
|
||
Ok(BucketStatus { bucket_id, bucket, writer_ids, deal_statuses }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod entity; | ||
pub mod store; | ||
pub mod messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use ink_prelude::vec::Vec; | ||
use ink_storage::{ | ||
collections::Vec as InkVec, | ||
traits, | ||
}; | ||
|
||
use crate::ddc_bucket::{AccountId, Error::*, Result}; | ||
|
||
use super::entity::{Bucket, BucketId, BucketParams}; | ||
|
||
#[derive(traits::SpreadLayout, Default)] | ||
#[cfg_attr(feature = "std", derive(traits::StorageLayout, Debug))] | ||
pub struct BucketStore(pub InkVec<Bucket>); | ||
|
||
impl BucketStore { | ||
pub fn create(&mut self, owner_id: AccountId, bucket_params: BucketParams) -> BucketId { | ||
let bucket = Bucket { | ||
owner_id, | ||
deal_ids: Vec::new(), | ||
bucket_params, | ||
}; | ||
let bucket_id = self.0.len(); | ||
self.0.push(bucket); | ||
bucket_id | ||
} | ||
|
||
pub fn get(&self, bucket_id: BucketId) -> Result<&Bucket> { | ||
self.0.get(bucket_id).ok_or(BucketDoesNotExist) | ||
} | ||
|
||
pub fn get_mut(&mut self, bucket_id: BucketId) -> Result<&mut Bucket> { | ||
self.0.get_mut(bucket_id).ok_or(BucketDoesNotExist) | ||
} | ||
} |
Oops, something went wrong.