Skip to content

Commit

Permalink
Merge pull request #464 from Cerebellum-Network/fix/batch-mmr-proofs
Browse files Browse the repository at this point in the history
Validating MMR proof for every batch during payout process + Optimizations
  • Loading branch information
yahortsaryk authored Nov 7, 2024
2 parents 66f927c + da97857 commit 400f180
Show file tree
Hide file tree
Showing 14 changed files with 1,040 additions and 834 deletions.
17 changes: 12 additions & 5 deletions pallets/ddc-customers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use ddc_primitives::{
cluster::{ClusterCreator, ClusterProtocol, ClusterQuery},
customer::{CustomerCharger, CustomerDepositor, CustomerVisitor},
},
BucketId, BucketVisitorError, ClusterId, CustomerUsage,
BucketId, ClusterId, CustomerUsage,
};
use frame_support::{
parameter_types,
Expand Down Expand Up @@ -251,6 +251,8 @@ pub mod pallet {
TransferFailed,
/// Bucket is already removed
AlreadyRemoved,
/// Bucket belongs to another cluster
ClusterMismatch,
}

#[pallet::genesis_config]
Expand Down Expand Up @@ -648,14 +650,19 @@ pub mod pallet {
}

impl<T: Config> BucketVisitor<T> for Pallet<T> {
fn get_bucket_owner_id(bucket_id: BucketId) -> Result<T::AccountId, DispatchError> {
let bucket = Self::buckets(bucket_id).ok_or(Error::<T>::BucketDoesNotExist)?;
Ok(bucket.owner_id)
}

fn get_total_customer_usage(
cluster_id: &ClusterId,
bucket_id: BucketId,
content_owner: &T::AccountId,
) -> Result<Option<CustomerUsage>, BucketVisitorError> {
let bucket = Self::buckets(bucket_id).ok_or(BucketVisitorError::NoBucketWithId)?;
ensure!(bucket.owner_id == *content_owner, BucketVisitorError::NotBucketOwner);
ensure!(bucket.cluster_id == *cluster_id, BucketVisitorError::IncorrectClusterId);
) -> Result<Option<CustomerUsage>, DispatchError> {
let bucket = Self::buckets(bucket_id).ok_or(Error::<T>::NoBucketWithId)?;
ensure!(bucket.owner_id == *content_owner, Error::<T>::NotBucketOwner);
ensure!(bucket.cluster_id == *cluster_id, Error::<T>::ClusterMismatch);

Ok(bucket.total_customers_usage)
}
Expand Down
22 changes: 16 additions & 6 deletions pallets/ddc-payouts/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! DdcPayouts pallet benchmarking.

use ddc_primitives::{traits::ValidatorVisitor, ClusterId, ClusterParams, ClusterProtocolParams};
use ddc_primitives::{
traits::ValidatorVisitor, ClusterId, ClusterParams, ClusterProtocolParams, NodePubKey,
};
pub use frame_benchmarking::{account, benchmarks, whitelist_account};
use frame_system::RawOrigin;
use sp_runtime::Perquintill;
use sp_runtime::{AccountId32, Perquintill};
use sp_std::prelude::*;

use super::*;
Expand Down Expand Up @@ -223,7 +225,7 @@ benchmarks! {
});

let batch_index: BatchIndex = 0;
let payers: Vec<(T::AccountId, BucketId, CustomerUsage)> = (0..b).map(|i| {
let payers: Vec<(NodePubKey, BucketId, CustomerUsage)> = (0..b).map(|i| {
let customer = create_account::<T>("customer", i, i);

if b % 2 == 0 {
Expand All @@ -241,8 +243,12 @@ benchmarks! {
number_of_puts: 5, // 5 puts
};
let bucket_id: BucketId = 1;
let node_key = NodePubKey::StoragePubKey(AccountId32::from([
48, 47, 147, 125, 243, 160, 236, 76, 101, 142, 129, 34, 67, 158, 116, 141, 34, 116, 66,
235, 212, 147, 206, 245, 33, 161, 225, 73, 67, 132, 67, 149,
]));

(customer, bucket_id, customer_usage)
(node_key, bucket_id, customer_usage)
}).collect();

}: _(RawOrigin::Signed(dac_account.clone()), cluster_id, era, batch_index, payers, MMRProof::default())
Expand Down Expand Up @@ -396,7 +402,7 @@ benchmarks! {
whitelist_account!(dac_account);

let batch_index: BatchIndex = 0;
let payees: Vec<(T::AccountId, NodeUsage)> = (0..b).map(|i| {
let payees: Vec<(NodePubKey, NodeUsage)> = (0..b).map(|i| {
let provider = create_account::<T>("provider", i, i);
endow_account::<T>(&provider, T::Currency::minimum_balance().saturated_into());
let node_usage = NodeUsage {
Expand All @@ -405,7 +411,11 @@ benchmarks! {
number_of_gets: 10, // 10 gets
number_of_puts: 5, // 5 puts
};
(provider, node_usage)
let node_key = NodePubKey::StoragePubKey(AccountId32::from([
48, 47, 147, 125, 243, 160, 236, 76, 101, 142, 129, 34, 67, 158, 116, 141, 34, 116, 66,
235, 212, 147, 206, 245, 33, 161, 225, 73, 67, 132, 67, 149,
]));
(node_key, node_usage)
}).collect();

}: _(RawOrigin::Signed(dac_account.clone()), cluster_id, era, batch_index, payees, MMRProof::default())
Expand Down
39 changes: 15 additions & 24 deletions pallets/ddc-payouts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ use ddc_primitives::{
pallet::PalletVisitor as PalletVisitorType,
payout::PayoutVisitor,
},
BatchIndex, BucketId, BucketVisitorError, ClusterId, CustomerUsage, DdcEra, MMRProof,
NodeUsage, PayoutError, PayoutState, MAX_PAYOUT_BATCH_COUNT, MAX_PAYOUT_BATCH_SIZE, MILLICENTS,
BatchIndex, BucketId, ClusterId, CustomerUsage, DdcEra, MMRProof, NodePubKey, NodeUsage,
PayoutError, PayoutState, MAX_PAYOUT_BATCH_COUNT, MAX_PAYOUT_BATCH_SIZE, MILLICENTS,
};
use frame_election_provider_support::SortedListProvider;
use frame_support::{
Expand Down Expand Up @@ -431,7 +431,7 @@ pub mod pallet {
cluster_id: ClusterId,
era: DdcEra,
batch_index: BatchIndex,
payers: Vec<(T::AccountId, BucketId, CustomerUsage)>,
payers: Vec<(NodePubKey, BucketId, CustomerUsage)>,
batch_proof: MMRProof,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
Expand Down Expand Up @@ -465,15 +465,17 @@ pub mod pallet {
cluster_id,
era,
batch_index,
billing_report.charging_max_batch_index,
&payers,
&batch_proof
),
Error::<T>::BatchValidationFailed
);

let mut updated_billing_report = billing_report;
for (customer_id, bucket_id, customer_usage) in payers {
log::info!("🏭send_charging_customers_batch get_customer_charge customer_id: {:?} - bucket_id: {:?} - era:{:?} - cluster-id:{:?}", Self::get_account_id_string(customer_id.clone()), bucket_id, era, cluster_id);
for (_node_key, bucket_id, customer_usage) in payers {
let customer_id = T::BucketVisitor::get_bucket_owner_id(bucket_id)?;

let mut customer_charge = get_customer_charge::<T>(
&cluster_id,
&customer_usage,
Expand Down Expand Up @@ -749,8 +751,7 @@ pub mod pallet {
cluster_id: ClusterId,
era: DdcEra,
batch_index: BatchIndex,
payees: Vec<(T::AccountId, NodeUsage)>, /* todo! we need to pass NodePubKey inside
* NodeUsage and more provider_id */
payees: Vec<(NodePubKey, NodeUsage)>,
batch_proof: MMRProof,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
Expand Down Expand Up @@ -782,6 +783,7 @@ pub mod pallet {
cluster_id,
era,
batch_index,
billing_report.rewarding_max_batch_index,
&payees,
&batch_proof
),
Expand All @@ -790,9 +792,9 @@ pub mod pallet {

let max_dust = MaxDust::get().saturated_into::<BalanceOf<T>>();
let mut updated_billing_report = billing_report.clone();
for (node_provider_id, delta_node_usage) in payees {
// todo! deduce node_provider_id from delta_node_usage.node_id
for (node_key, delta_node_usage) in payees {
// todo! get T::NodeVisitor::get_total_usage(delta_node_usage.node_id).stored_bytes
let node_provider_id = T::NodeVisitor::get_node_provider_id(&node_key)?;
let mut total_node_stored_bytes: i64 = 0;

total_node_stored_bytes = total_node_stored_bytes
Expand Down Expand Up @@ -1084,7 +1086,7 @@ pub mod pallet {
customer_id: &T::AccountId,
start_era: i64,
end_era: i64,
) -> Result<CustomerCharge, Error<T>> {
) -> Result<CustomerCharge, DispatchError> {
let mut total = CustomerCharge::default();

let pricing = T::ClusterProtocol::get_pricing_params(cluster_id)
Expand All @@ -1104,8 +1106,7 @@ pub mod pallet {
Perquintill::from_rational(duration_seconds as u64, seconds_in_month as u64);

let mut total_stored_bytes: i64 =
T::BucketVisitor::get_total_customer_usage(cluster_id, bucket_id, customer_id)
.map_err(Into::<Error<T>>::into)?
T::BucketVisitor::get_total_customer_usage(cluster_id, bucket_id, customer_id)?
.map_or(0, |customer_usage| customer_usage.stored_bytes);

total_stored_bytes = total_stored_bytes
Expand All @@ -1132,16 +1133,6 @@ pub mod pallet {
Ok(total)
}

impl<T> From<BucketVisitorError> for Error<T> {
fn from(error: BucketVisitorError) -> Self {
match error {
BucketVisitorError::NoBucketWithId => Error::<T>::NoBucketWithId,
BucketVisitorError::NotBucketOwner => Error::<T>::NotBucketOwner,
BucketVisitorError::IncorrectClusterId => Error::<T>::IncorrectClusterId,
}
}
}

#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub feeder_account: Option<T::AccountId>,
Expand Down Expand Up @@ -1220,7 +1211,7 @@ pub mod pallet {
cluster_id: ClusterId,
era_id: DdcEra,
batch_index: BatchIndex,
payers: &[(T::AccountId, BucketId, CustomerUsage)],
payers: &[(NodePubKey, BucketId, CustomerUsage)],
batch_proof: MMRProof,
) -> DispatchResult {
log::info!(
Expand Down Expand Up @@ -1277,7 +1268,7 @@ pub mod pallet {
cluster_id: ClusterId,
era_id: DdcEra,
batch_index: BatchIndex,
payees: &[(T::AccountId, NodeUsage)],
payees: &[(NodePubKey, NodeUsage)],
batch_proof: MMRProof,
) -> DispatchResult {
log::info!(
Expand Down
Loading

0 comments on commit 400f180

Please sign in to comment.