From 3f3ca38f22e01842c45bccf9da4902313e5841fa Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 10:52:54 +0500 Subject: [PATCH 01/10] Allow root origin to set cluster last paid era --- pallets/ddc-clusters/src/lib.rs | 12 ++++++++++++ pallets/ddc-clusters/src/weights.rs | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/pallets/ddc-clusters/src/lib.rs b/pallets/ddc-clusters/src/lib.rs index ed86010ea..79db98da8 100644 --- a/pallets/ddc-clusters/src/lib.rs +++ b/pallets/ddc-clusters/src/lib.rs @@ -430,6 +430,18 @@ pub mod pallet { Self::do_join_cluster(cluster, node_pub_key) } + + #[pallet::call_index(6)] + #[pallet::weight(::WeightInfo::set_last_paid_era())] + pub fn set_last_paid_era( + origin: OriginFor, + cluster_id: ClusterId, + era_id: DdcEra, + ) -> DispatchResult { + ensure_root(origin)?; + + >::set_last_paid_era(&cluster_id, era_id) + } } impl Pallet { diff --git a/pallets/ddc-clusters/src/weights.rs b/pallets/ddc-clusters/src/weights.rs index 83ce438dc..8317a376b 100644 --- a/pallets/ddc-clusters/src/weights.rs +++ b/pallets/ddc-clusters/src/weights.rs @@ -34,6 +34,7 @@ pub trait WeightInfo { fn remove_node() -> Weight; fn set_cluster_params() -> Weight; fn validate_node() -> Weight; + fn set_last_paid_era() -> Weight; } /// Weights for pallet_ddc_clusters using the Substrate node and recommended hardware. @@ -141,6 +142,12 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + + fn set_last_paid_era() -> Weight { + Weight::from_parts(0_u64, 0) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } // For backwards compatibility and tests @@ -247,4 +254,10 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } + + fn set_last_paid_era() -> Weight { + Weight::from_parts(0_u64, 0) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } } From 374e6c17268f86e3bbbfc6160906eceeb49abcc0 Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 10:54:16 +0500 Subject: [PATCH 02/10] Bump `spec_version` --- runtime/cere-dev/src/lib.rs | 2 +- runtime/cere/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index cf0cc2af2..6c769115d 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -153,7 +153,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 61005, + spec_version: 61006, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 23, diff --git a/runtime/cere/src/lib.rs b/runtime/cere/src/lib.rs index c4f0ef7f9..eee86d521 100644 --- a/runtime/cere/src/lib.rs +++ b/runtime/cere/src/lib.rs @@ -147,7 +147,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 61005, + spec_version: 61006, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 23, From 5588d77569b2672906fb5f223327305d822b1d02 Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 11:07:33 +0500 Subject: [PATCH 03/10] Fix tests regression --- pallets/ddc-clusters/src/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/ddc-clusters/src/tests.rs b/pallets/ddc-clusters/src/tests.rs index d85f42288..f5f6e1758 100644 --- a/pallets/ddc-clusters/src/tests.rs +++ b/pallets/ddc-clusters/src/tests.rs @@ -590,7 +590,7 @@ fn set_last_validated_era_works() { // Cluster doesn't exist assert_noop!( - DdcClusters::set_last_paid_era(&cluster_id, era_id), + >::set_last_paid_era(&cluster_id, era_id), Error::::ClusterDoesNotExist ); @@ -619,7 +619,7 @@ fn set_last_validated_era_works() { } )); - assert_ok!(DdcClusters::set_last_paid_era(&cluster_id, era_id)); + assert_ok!(>::set_last_paid_era(&cluster_id, era_id)); let updated_cluster = DdcClusters::clusters(cluster_id).unwrap(); assert_eq!(updated_cluster.last_paid_era, era_id); From b25f1833fe74317170d29943e2c1c4690dd80fb1 Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 18:01:32 +0500 Subject: [PATCH 04/10] Remove `set_last_paid_era` extrinsic --- pallets/ddc-clusters/src/lib.rs | 12 ------------ pallets/ddc-clusters/src/weights.rs | 13 ------------- 2 files changed, 25 deletions(-) diff --git a/pallets/ddc-clusters/src/lib.rs b/pallets/ddc-clusters/src/lib.rs index 79db98da8..ed86010ea 100644 --- a/pallets/ddc-clusters/src/lib.rs +++ b/pallets/ddc-clusters/src/lib.rs @@ -430,18 +430,6 @@ pub mod pallet { Self::do_join_cluster(cluster, node_pub_key) } - - #[pallet::call_index(6)] - #[pallet::weight(::WeightInfo::set_last_paid_era())] - pub fn set_last_paid_era( - origin: OriginFor, - cluster_id: ClusterId, - era_id: DdcEra, - ) -> DispatchResult { - ensure_root(origin)?; - - >::set_last_paid_era(&cluster_id, era_id) - } } impl Pallet { diff --git a/pallets/ddc-clusters/src/weights.rs b/pallets/ddc-clusters/src/weights.rs index 8317a376b..83ce438dc 100644 --- a/pallets/ddc-clusters/src/weights.rs +++ b/pallets/ddc-clusters/src/weights.rs @@ -34,7 +34,6 @@ pub trait WeightInfo { fn remove_node() -> Weight; fn set_cluster_params() -> Weight; fn validate_node() -> Weight; - fn set_last_paid_era() -> Weight; } /// Weights for pallet_ddc_clusters using the Substrate node and recommended hardware. @@ -142,12 +141,6 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - - fn set_last_paid_era() -> Weight { - Weight::from_parts(0_u64, 0) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } } // For backwards compatibility and tests @@ -254,10 +247,4 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - - fn set_last_paid_era() -> Weight { - Weight::from_parts(0_u64, 0) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } } From 27474823ff51fd6e7618faa19fc96cdb4b9ecf5c Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 18:03:03 +0500 Subject: [PATCH 05/10] Default trait for primitives --- primitives/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 3c59c3f17..d887c8be2 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -409,6 +409,20 @@ pub struct EraValidation { pub status: EraValidationStatus, } +impl Default for EraValidation { + fn default() -> Self { + EraValidation { + validators: Default::default(), + start_era: Default::default(), + end_era: Default::default(), + payers_merkle_root_hash: Default::default(), + payees_merkle_root_hash: Default::default(), + status: EraValidationStatus::PayoutSkipped, + } + } +} + +#[derive(Default)] pub struct BillingReportParams { pub cluster_id: ClusterId, pub era: DdcEra, From f870601ecc189a1f94943cae664abe3aa0b487e0 Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 18:04:47 +0500 Subject: [PATCH 06/10] Alow `create_billing_report` at runtime --- pallets/ddc-payouts/src/lib.rs | 9 +++------ pallets/ddc-verification/src/lib.rs | 4 ++-- pallets/ddc-verification/src/mock.rs | 1 - primitives/src/traits/payout.rs | 7 ++----- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index 33b50de92..df7c8a448 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -21,17 +21,15 @@ mod tests; pub mod migrations; -#[cfg(feature = "runtime-benchmarks")] -use ddc_primitives::BillingReportParams; use ddc_primitives::{ traits::{ bucket::BucketManager, cluster::ClusterProtocol as ClusterProtocolType, customer::CustomerCharger as CustomerChargerType, node::NodeManager, pallet::PalletVisitor as PalletVisitorType, payout::PayoutProcessor, }, - BatchIndex, BucketId, BucketUsage, ClusterId, CustomerCharge, DdcEra, MMRProof, NodePubKey, - NodeUsage, PayoutError, PayoutState, ProviderReward, MAX_PAYOUT_BATCH_COUNT, - MAX_PAYOUT_BATCH_SIZE, MILLICENTS, + BatchIndex, BillingReportParams, BucketId, BucketUsage, ClusterId, CustomerCharge, DdcEra, + MMRProof, NodePubKey, NodeUsage, PayoutError, PayoutState, ProviderReward, + MAX_PAYOUT_BATCH_COUNT, MAX_PAYOUT_BATCH_SIZE, MILLICENTS, }; use frame_election_provider_support::SortedListProvider; use frame_support::{ @@ -1160,7 +1158,6 @@ pub mod pallet { Ok(None) } - #[cfg(feature = "runtime-benchmarks")] fn create_billing_report(vault: T::AccountId, params: BillingReportParams) { let mut charging_processed_batches = BoundedBTreeSet::::new(); diff --git a/pallets/ddc-verification/src/lib.rs b/pallets/ddc-verification/src/lib.rs index 1be8ebe11..423e7ef06 100644 --- a/pallets/ddc-verification/src/lib.rs +++ b/pallets/ddc-verification/src/lib.rs @@ -19,8 +19,8 @@ use ddc_primitives::{ ClusterManager, ClusterValidator, CustomerVisitor, NodeManager, PayoutProcessor, ValidatorVisitor, }, - ActivityHash, BatchIndex, BucketUsage, ClusterId, ClusterStatus, DdcEra, EraValidation, - EraValidationStatus, MMRProof, NodeParams, NodePubKey, NodeUsage, PayoutState, + ActivityHash, BatchIndex, BillingReportParams, BucketUsage, ClusterId, ClusterStatus, DdcEra, + EraValidation, EraValidationStatus, MMRProof, NodeParams, NodePubKey, NodeUsage, PayoutState, StorageNodeParams, }; use frame_support::{ diff --git a/pallets/ddc-verification/src/mock.rs b/pallets/ddc-verification/src/mock.rs index 48154207e..677d2c3ad 100644 --- a/pallets/ddc-verification/src/mock.rs +++ b/pallets/ddc-verification/src/mock.rs @@ -513,7 +513,6 @@ impl PayoutProcessor for MockPayoutProcessor { PayoutState::NotInitialized } - #[cfg(feature = "runtime-benchmarks")] fn create_billing_report(_vault: T::AccountId, _params: BillingReportParams) { unimplemented!() } diff --git a/primitives/src/traits/payout.rs b/primitives/src/traits/payout.rs index 351617e6f..1a0907606 100644 --- a/primitives/src/traits/payout.rs +++ b/primitives/src/traits/payout.rs @@ -1,10 +1,8 @@ use sp_runtime::DispatchResult; -#[cfg(feature = "runtime-benchmarks")] -use crate::BillingReportParams; use crate::{ - BatchIndex, BucketId, BucketUsage, ClusterId, DdcEra, MMRProof, NodePubKey, NodeUsage, - PayoutError, PayoutState, + BatchIndex, BillingReportParams, BucketId, BucketUsage, ClusterId, DdcEra, MMRProof, + NodePubKey, NodeUsage, PayoutError, PayoutState, }; pub trait PayoutProcessor { @@ -66,6 +64,5 @@ pub trait PayoutProcessor { era_id: DdcEra, ) -> Result, PayoutError>; - #[cfg(feature = "runtime-benchmarks")] fn create_billing_report(vault: T::AccountId, params: BillingReportParams); } From 1b745359708fda232f13fe28a8fcd23eaf964f65 Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 18:05:39 +0500 Subject: [PATCH 07/10] Separate `set_era_validations` body --- pallets/ddc-verification/src/lib.rs | 45 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/pallets/ddc-verification/src/lib.rs b/pallets/ddc-verification/src/lib.rs index 423e7ef06..0298a46e6 100644 --- a/pallets/ddc-verification/src/lib.rs +++ b/pallets/ddc-verification/src/lib.rs @@ -1272,6 +1272,33 @@ pub mod pallet { } impl Pallet { + pub(crate) fn do_set_era_validations( + cluster_id: &ClusterId, + era_id: DdcEra, + ) -> DispatchResult { + let era_validations = >::get(cluster_id, era_id); + + if era_validations.is_none() { + let mut era_validation = EraValidation { + status: EraValidationStatus::PayoutSkipped, + ..Default::default() + }; + + let signed_validators = era_validation + .validators + .entry((ActivityHash::default(), ActivityHash::default())) + .or_insert_with(Vec::new); + + let validators = >::get(); + + signed_validators.extend(validators); + + >::insert(cluster_id, era_id, era_validation); + } + + Ok(()) + } + #[allow(clippy::type_complexity)] pub(crate) fn process_dac_era( cluster_id: &ClusterId, @@ -3960,22 +3987,12 @@ pub mod pallet { era_id: DdcEra, ) -> DispatchResult { ensure_root(origin)?; - let era_validations = >::get(cluster_id, era_id); - if era_validations.is_none() { - let mut era_validation = EraValidation { - payers_merkle_root_hash: ActivityHash::default(), - payees_merkle_root_hash: ActivityHash::default(), - start_era: Default::default(), - end_era: Default::default(), - validators: Default::default(), - status: EraValidationStatus::PayoutSkipped, - }; + Self::do_set_era_validations(&cluster_id, era_id)?; + Self::deposit_event(Event::::EraValidationReady { cluster_id, era_id }); - let signed_validators = era_validation - .validators - .entry((ActivityHash::default(), ActivityHash::default())) - .or_insert_with(Vec::new); + Ok(()) + } let validators = >::get(); From 64c47a4badba28575e4e5ce77589e3fffec9084f Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Wed, 20 Nov 2024 18:06:36 +0500 Subject: [PATCH 08/10] New `skip_dac_validation_to_era` extrinsic --- pallets/ddc-verification/src/lib.rs | 35 +++++++++++++++++++++---- pallets/ddc-verification/src/weights.rs | 13 +++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/pallets/ddc-verification/src/lib.rs b/pallets/ddc-verification/src/lib.rs index 0298a46e6..5b5b3cbb6 100644 --- a/pallets/ddc-verification/src/lib.rs +++ b/pallets/ddc-verification/src/lib.rs @@ -511,6 +511,8 @@ pub mod pallet { FailToVerifyMerkleProof, /// No Era Validation exist NoEraValidation, + /// Given era is already validated and paid. + EraAlreadyPaid, } /// Era validations @@ -3994,14 +3996,37 @@ pub mod pallet { Ok(()) } - let validators = >::get(); + /// Continue DAC validation from an era after a given one. It updates `last_paid_era` of a + /// given cluster, creates an empty billing report with a finalized state, and sets an empty + /// validation result on validators (in case it does not exist yet). + #[pallet::call_index(12)] + #[pallet::weight(::WeightInfo::skip_dac_validation_to_era())] + pub fn skip_dac_validation_to_era( + origin: OriginFor, + cluster_id: ClusterId, + era_id: DdcEra, + ) -> DispatchResult { + ensure_root(origin)?; + ensure!( + era_id > T::ClusterValidator::get_last_paid_era(&cluster_id)?, + Error::::EraAlreadyPaid + ); - signed_validators.extend(validators); + Self::do_set_era_validations(&cluster_id, era_id)?; - >::insert(cluster_id, era_id, era_validation); - } + let billing_report_params = BillingReportParams { + cluster_id, + era: era_id, + state: PayoutState::Finalized, + ..Default::default() + }; - Self::deposit_event(Event::::EraValidationReady { cluster_id, era_id }); + T::PayoutProcessor::create_billing_report( + T::AccountId::decode(&mut [0u8; 32].as_slice()).unwrap(), + billing_report_params, + ); + + T::ClusterValidator::set_last_paid_era(&cluster_id, era_id)?; Ok(()) } diff --git a/pallets/ddc-verification/src/weights.rs b/pallets/ddc-verification/src/weights.rs index 4d217b25d..f5ed1d0c8 100644 --- a/pallets/ddc-verification/src/weights.rs +++ b/pallets/ddc-verification/src/weights.rs @@ -39,6 +39,7 @@ pub trait WeightInfo { fn end_billing_report() -> Weight; fn emit_consensus_errors(b: u32, ) -> Weight; fn set_era_validations() -> Weight; + fn skip_dac_validation_to_era() -> Weight; } /// Weights for pallet_ddc_verification using the Substrate node and recommended hardware. @@ -225,6 +226,12 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + + fn skip_dac_validation_to_era() -> Weight { + Weight::from_parts(0_u64, 0) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } } // For backwards compatibility and tests @@ -410,4 +417,10 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + + fn skip_dac_validation_to_era() -> Weight { + Weight::from_parts(0_u64, 0) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } } From dc1c3a915361c554b13834a19c98de9a0d998d1d Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Thu, 21 Nov 2024 10:04:08 +0500 Subject: [PATCH 09/10] Better name for validation skipping fn --- pallets/ddc-verification/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/ddc-verification/src/lib.rs b/pallets/ddc-verification/src/lib.rs index 5b5b3cbb6..483b40e3b 100644 --- a/pallets/ddc-verification/src/lib.rs +++ b/pallets/ddc-verification/src/lib.rs @@ -1274,7 +1274,7 @@ pub mod pallet { } impl Pallet { - pub(crate) fn do_set_era_validations( + pub(crate) fn do_skip_era_validation( cluster_id: &ClusterId, era_id: DdcEra, ) -> DispatchResult { @@ -3990,7 +3990,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - Self::do_set_era_validations(&cluster_id, era_id)?; + Self::do_skip_era_validation(&cluster_id, era_id)?; Self::deposit_event(Event::::EraValidationReady { cluster_id, era_id }); Ok(()) @@ -4012,7 +4012,7 @@ pub mod pallet { Error::::EraAlreadyPaid ); - Self::do_set_era_validations(&cluster_id, era_id)?; + Self::do_skip_era_validation(&cluster_id, era_id)?; let billing_report_params = BillingReportParams { cluster_id, From 95c6f7aa512b1309757721452dca86511bee3c77 Mon Sep 17 00:00:00 2001 From: "Alisher A. Khassanov" Date: Thu, 21 Nov 2024 10:06:16 +0500 Subject: [PATCH 10/10] Add doc comment for `set_era_validations` call --- pallets/ddc-verification/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pallets/ddc-verification/src/lib.rs b/pallets/ddc-verification/src/lib.rs index 483b40e3b..7e8d7a833 100644 --- a/pallets/ddc-verification/src/lib.rs +++ b/pallets/ddc-verification/src/lib.rs @@ -3981,6 +3981,10 @@ pub mod pallet { Ok(()) } + /// Set PayoutSkipped state of a given era if it is not validated yet. Otherwise does + /// nothing. + /// + /// Emits `EraValidationReady`. #[pallet::call_index(11)] #[pallet::weight(::WeightInfo::set_era_validations())] pub fn set_era_validations(