Skip to content

Commit

Permalink
wip: adding billing fingerprint
Browse files Browse the repository at this point in the history
  • Loading branch information
yahortsaryk committed Nov 26, 2024
1 parent d781db9 commit d2451e3
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 56 deletions.
76 changes: 42 additions & 34 deletions pallets/ddc-payouts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use ddc_primitives::{
pallet::PalletVisitor as PalletVisitorType, payout::PayoutProcessor,
},
BatchIndex, BillingReportParams, BucketId, BucketUsage, ClusterId, CustomerCharge, DdcEra,
MMRProof, NodePubKey, NodeUsage, PayableUsageHash, PayoutError, PayoutState, ProviderReward,
MAX_PAYOUT_BATCH_COUNT, MAX_PAYOUT_BATCH_SIZE, MILLICENTS,
Fingerprint, MMRProof, NodePubKey, NodeUsage, PayableUsageHash, PayoutError, PayoutState,
ProviderReward, MAX_PAYOUT_BATCH_COUNT, MAX_PAYOUT_BATCH_SIZE, MILLICENTS,
};
use frame_election_provider_support::SortedListProvider;
use frame_support::{
Expand All @@ -42,7 +42,6 @@ use frame_support::{
use frame_system::pallet_prelude::*;
pub use pallet::*;
use scale_info::prelude::string::String;
use sp_core::H256;
use sp_runtime::{
traits::{Convert, Hash},
AccountId32, PerThing, Perquintill,
Expand All @@ -66,8 +65,6 @@ pub type VoteScoreOf<T> =
<T as frame_system::Config>::AccountId,
>>::Score;

pub type Fingerprint = H256;

parameter_types! {
pub MaxBatchesCount: u16 = MAX_PAYOUT_BATCH_COUNT;
pub MaxDust: u128 = MILLICENTS;
Expand Down Expand Up @@ -238,7 +235,8 @@ pub mod pallet {
IncorrectClusterId,
ClusterProtocolParamsNotSet,
TotalStoredBytesLessThanZero,
FingerprintIsAlreadyCommitted,
BillingFingerprintIsCommitted,
BillingFingerprintDoesNotExist,
}

#[pallet::storage]
Expand Down Expand Up @@ -267,8 +265,7 @@ pub mod pallet {
pub struct BillingReport<T: Config> {
pub state: PayoutState,
pub vault: T::AccountId,
pub start_era: i64,
pub end_era: i64,
pub fingerprint: Fingerprint,
pub total_customer_charge: CustomerCharge,
pub total_distributed_reward: u128,
pub total_node_usage: NodeUsage,
Expand All @@ -285,8 +282,7 @@ pub mod pallet {
Self {
state: PayoutState::default(),
vault: T::PalletId::get().into_account_truncating(),
start_era: Zero::zero(),
end_era: Zero::zero(),
fingerprint: Default::default(),
total_customer_charge: CustomerCharge::default(),
total_distributed_reward: Zero::zero(),
total_node_usage: NodeUsage::default(),
Expand All @@ -313,7 +309,7 @@ pub mod pallet {
}

#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)]
pub struct BillingReportFingerprint<AccountId> {
pub struct BillingFingerprint<AccountId> {
pub cluster_id: ClusterId,
pub era_id: DdcEra,
pub start_era: i64,
Expand All @@ -323,7 +319,7 @@ pub mod pallet {
pub validators: BTreeSet<AccountId>,
}

impl<AccountId> BillingReportFingerprint<AccountId> {
impl<AccountId> BillingFingerprint<AccountId> {
fn selective_hash<T: Config>(&self) -> Fingerprint {
let mut data = self.cluster_id.encode();
data.extend_from_slice(&self.era_id.encode());
Expand All @@ -332,15 +328,15 @@ pub mod pallet {
data.extend_from_slice(&self.payers_merkle_root.encode());
data.extend_from_slice(&self.payees_merkle_root.encode());
// we truncate the `validators` field on purpose as it's appendable collection that is
// used for reaching the quorum on the fingerprint
// used for reaching the quorum on the billing fingerprint
T::FingerprintHasher::hash(&data).into()
}
}

#[pallet::storage]
#[pallet::getter(fn fingerprints)]
pub type Fingerprints<T: Config> =
StorageMap<_, Blake2_128Concat, Fingerprint, BillingReportFingerprint<T::AccountId>>;
pub type BillingFingerprints<T: Config> =
StorageMap<_, Blake2_128Concat, Fingerprint, BillingFingerprint<T::AccountId>>;

#[pallet::call]
impl<T: Config> Pallet<T> {}
Expand Down Expand Up @@ -593,7 +589,7 @@ pub mod pallet {
}

impl<T: Config> PayoutProcessor<T> for Pallet<T> {
fn commit_billing_report_fingerprint(
fn commit_billing_fingerprint(
validator: T::AccountId,
cluster_id: ClusterId,
era_id: DdcEra,
Expand All @@ -606,7 +602,7 @@ pub mod pallet {
ensure!(payers_merkle_root != Default::default(), Error::<T>::BadRequest);
ensure!(payees_merkle_root != Default::default(), Error::<T>::BadRequest);

let inited_fingerprint = BillingReportFingerprint::<T::AccountId> {
let inited_fingerprint = BillingFingerprint::<T::AccountId> {
cluster_id,
era_id,
start_era,
Expand All @@ -617,40 +613,37 @@ pub mod pallet {
};
let hash = inited_fingerprint.selective_hash::<T>();

let mut fingerprint = if let Some(commited_fingerprint) = Fingerprints::<T>::get(hash) {
commited_fingerprint
} else {
inited_fingerprint
};
let mut fingerprint =
if let Some(commited_fingerprint) = BillingFingerprints::<T>::get(hash) {
commited_fingerprint
} else {
inited_fingerprint
};

ensure!(
fingerprint.validators.insert(validator),
Error::<T>::FingerprintIsAlreadyCommitted
Error::<T>::BillingFingerprintIsCommitted
);

Fingerprints::<T>::insert(hash, fingerprint);
BillingFingerprints::<T>::insert(hash, fingerprint);

Ok(())
}

fn begin_billing_report(
cluster_id: ClusterId,
era: DdcEra,
start_era: i64,
end_era: i64,
fingerprint: Fingerprint,
) -> DispatchResult {
ensure!(
ActiveBillingReports::<T>::try_get(cluster_id, era).is_err(),
Error::<T>::NotExpectedState
);

ensure!(end_era > start_era, Error::<T>::BadRequest);

let billing_report = BillingReport::<T> {
vault: Self::account_id(),
fingerprint,
state: PayoutState::Initialized,
start_era,
end_era,
..Default::default()
};
ActiveBillingReports::<T>::insert(cluster_id, era, billing_report);
Expand Down Expand Up @@ -723,6 +716,9 @@ pub mod pallet {
Error::<T>::BatchValidationFailed
);

let fingerprint = BillingFingerprints::<T>::try_get(billing_report.fingerprint)
.map_err(|_| Error::<T>::BillingFingerprintDoesNotExist)?;

let mut updated_billing_report = billing_report;
for (_node_key, bucket_ref, customer_usage) in payers {
let bucket_id = *bucket_ref;
Expand All @@ -733,8 +729,8 @@ pub mod pallet {
customer_usage,
bucket_id,
&customer_id,
updated_billing_report.start_era,
updated_billing_report.end_era,
fingerprint.start_era,
fingerprint.end_era,
)?;
let total_customer_charge = (|| -> Option<u128> {
customer_charge
Expand Down Expand Up @@ -1253,11 +1249,23 @@ pub mod pallet {
.expect("Rewarding batch to be inserted");
}

let billing_fingerprint = BillingFingerprint::<T::AccountId> {
cluster_id: params.cluster_id.clone(),
era_id: params.era.clone(),
start_era: params.start_era.clone(),
end_era: params.end_era.clone(),
payers_merkle_root: Default::default(),
payees_merkle_root: Default::default(),
validators: Default::default(),
};

let fingerprint = billing_fingerprint.selective_hash::<T>();
BillingFingerprints::<T>::insert(fingerprint, billing_fingerprint);

let billing_report = BillingReport::<T> {
vault,
start_era: params.start_era,
end_era: params.end_era,
state: params.state,
fingerprint,
total_customer_charge: params.total_customer_charge,
total_distributed_reward: params.total_distributed_reward,
total_node_usage: params.total_node_usage,
Expand Down
30 changes: 16 additions & 14 deletions pallets/ddc-verification/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use ddc_primitives::{
ValidatorVisitor,
},
ActivityHash, BatchIndex, BillingReportParams, BucketUsage, ClusterId, ClusterStatus, DdcEra,
EraValidation, EraValidationStatus, MMRProof, NodeParams, NodePubKey, NodeUsage,
PayableUsageHash, PayoutState, StorageNodeParams,
EraValidation, EraValidationStatus, MMRProof, NodeParams, NodePubKey, NodeUsage, PayoutState,
StorageNodeParams,
};
use frame_support::{
pallet_prelude::*,
Expand Down Expand Up @@ -84,7 +84,9 @@ pub(crate) type BalanceOf<T> =
#[frame_support::pallet]
pub mod pallet {

use ddc_primitives::{AggregatorInfo, BucketId, MergeActivityHash, DAC_VERIFICATION_KEY_TYPE};
use ddc_primitives::{
AggregatorInfo, BucketId, Fingerprint, MergeActivityHash, DAC_VERIFICATION_KEY_TYPE,
};
use frame_support::PalletId;
use sp_core::crypto::AccountId32;
use sp_runtime::SaturatedConversion;
Expand Down Expand Up @@ -1168,15 +1170,14 @@ pub mod pallet {
define_payout_step_function!(
step_begin_billing_report,
prepare_begin_billing_report,
|cluster_id: &ClusterId, (era_id, start_era, end_era)| Call::begin_billing_report {
|cluster_id: &ClusterId, (era_id, fingerprint)| Call::begin_billing_report {
cluster_id: *cluster_id,
era_id,
start_era,
end_era,
fingerprint
},
|prepared_data: &(DdcEra, _, _)| prepared_data.0,
|prepared_data: &(DdcEra, _)| prepared_data.0,
"🗓️ ",
|cluster_id: &ClusterId, (era_id, _, _)| OCWError::BeginBillingReportTransactionError {
|cluster_id: &ClusterId, (era_id, _)| OCWError::BeginBillingReportTransactionError {
cluster_id: *cluster_id,
era_id,
}
Expand Down Expand Up @@ -1771,9 +1772,11 @@ pub mod pallet {
#[allow(dead_code)]
pub(crate) fn prepare_begin_billing_report(
cluster_id: &ClusterId,
) -> Result<Option<(DdcEra, i64, i64)>, Vec<OCWError>> {
Ok(Self::get_era_for_payout(cluster_id, EraValidationStatus::ReadyForPayout))
.map_err(|e| vec![e])
) -> Result<Option<(DdcEra, Fingerprint)>, Vec<OCWError>> {
// Ok(Self::get_era_for_payout(cluster_id, EraValidationStatus::ReadyForPayout))
// .map_err(|e| vec![e])
let era = Self::get_era_for_payout(cluster_id, EraValidationStatus::ReadyForPayout);
Ok(Some((era.unwrap().0, Default::default())))
}

pub(crate) fn prepare_begin_charging_customers(
Expand Down Expand Up @@ -3438,13 +3441,12 @@ pub mod pallet {
origin: OriginFor<T>,
cluster_id: ClusterId,
era_id: DdcEra,
start_era: i64,
end_era: i64,
fingerprint: Fingerprint,
) -> DispatchResult {
let sender = ensure_signed(origin.clone())?;
ensure!(Self::is_ocw_validator(sender.clone()), Error::<T>::Unauthorized);

T::PayoutProcessor::begin_billing_report(cluster_id, era_id, start_era, end_era)?;
T::PayoutProcessor::begin_billing_report(cluster_id, era_id, fingerprint)?;

EraValidations::<T>::try_mutate(
cluster_id,
Expand Down
5 changes: 2 additions & 3 deletions pallets/ddc-verification/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ddc_primitives::{
crypto, sr25519,
traits::{ClusterManager, ClusterQuery},
BucketId, ClusterNodeKind, ClusterNodeState, ClusterNodeStatus, ClusterNodesStats,
ClusterStatus, PayoutError, PayoutState, StorageNodeMode, StorageNodePubKey,
ClusterStatus, Fingerprint, PayoutError, PayoutState, StorageNodeMode, StorageNodePubKey,
MAX_PAYOUT_BATCH_COUNT, MAX_PAYOUT_BATCH_SIZE,
};
#[cfg(feature = "runtime-benchmarks")]
Expand Down Expand Up @@ -432,8 +432,7 @@ impl<T: Config> PayoutProcessor<T> for MockPayoutProcessor {
fn begin_billing_report(
_cluster_id: ClusterId,
_era_id: DdcEra,
_start_era: i64,
_end_era: i64,
_fingerprint: Fingerprint,
) -> DispatchResult {
unimplemented!()
}
Expand Down
1 change: 1 addition & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub type ClusterNodesCount = u16;
pub type StorageNodePubKey = AccountId32;
pub type ActivityHash = [u8; 32]; // todo: rename to `DeltaUsageHash`
pub type PayableUsageHash = H256;
pub type Fingerprint = H256;

pub type BatchIndex = u16;
pub const AVG_SECONDS_MONTH: i64 = 2630016; // 30.44 * 24.0 * 3600.0;
Expand Down
9 changes: 4 additions & 5 deletions primitives/src/traits/payout.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use sp_runtime::DispatchResult;

use crate::{
BatchIndex, BillingReportParams, BucketId, BucketUsage, ClusterId, DdcEra, MMRProof,
NodePubKey, NodeUsage, PayableUsageHash, PayoutError, PayoutState,
BatchIndex, BillingReportParams, BucketId, BucketUsage, ClusterId, DdcEra, Fingerprint,
MMRProof, NodePubKey, NodeUsage, PayableUsageHash, PayoutError, PayoutState,
};

pub trait PayoutProcessor<T: frame_system::Config> {
fn commit_billing_report_fingerprint(
fn commit_billing_fingerprint(
validator: T::AccountId,
cluster_id: ClusterId,
era_id: DdcEra,
Expand All @@ -19,8 +19,7 @@ pub trait PayoutProcessor<T: frame_system::Config> {
fn begin_billing_report(
cluster_id: ClusterId,
era_id: DdcEra,
start_era: i64,
end_era: i64,
fingerprint: Fingerprint,
) -> DispatchResult;

fn begin_charging_customers(
Expand Down

0 comments on commit d2451e3

Please sign in to comment.