diff --git a/Cargo.lock b/Cargo.lock index 2c7a0befd1..e8705c522f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8272,6 +8272,7 @@ version = "1.0.0" dependencies = [ "cfg-mocks", "cfg-traits", + "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec 3.6.5", diff --git a/pallets/oracle-data-collection/src/lib.rs b/pallets/oracle-data-collection/src/lib.rs index d88a21af7f..57ee821222 100644 --- a/pallets/oracle-data-collection/src/lib.rs +++ b/pallets/oracle-data-collection/src/lib.rs @@ -369,6 +369,7 @@ pub mod types { storage::{bounded_btree_map::BoundedBTreeMap, bounded_vec::BoundedVec}, }; use sp_runtime::{traits::Zero, RuntimeDebug}; + use sp_std::vec::Vec; use crate::pallet::{Config, Error}; diff --git a/pallets/oracle-feed/Cargo.toml b/pallets/oracle-feed/Cargo.toml index d1dfba02fd..63bd880217 100644 --- a/pallets/oracle-feed/Cargo.toml +++ b/pallets/oracle-feed/Cargo.toml @@ -22,6 +22,9 @@ sp-runtime = { workspace = true } cfg-traits = { workspace = true } +# Optionals for benchmarking +frame-benchmarking = { workspace = true, optional = true } + [dev-dependencies] cfg-mocks = { workspace = true, features = ["std"] } @@ -32,6 +35,15 @@ std = [ "scale-info/std", "frame-support/std", "frame-system/std", + "frame-benchmarking?/std", "sp-runtime/std", "cfg-traits/std", ] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "cfg-traits/runtime-benchmarks", + "cfg-mocks/runtime-benchmarks", +] diff --git a/pallets/oracle-feed/src/benchmarking.rs b/pallets/oracle-feed/src/benchmarking.rs new file mode 100644 index 0000000000..317c7314bf --- /dev/null +++ b/pallets/oracle-feed/src/benchmarking.rs @@ -0,0 +1,47 @@ +use frame_benchmarking::{v2::*, whitelisted_caller}; +use frame_system::RawOrigin; + +use crate::pallet::{Call, Config, Pallet}; + +#[benchmarks( + where + T::OracleKey: From, + T::OracleValue: Default, +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn feed_first() -> Result<(), BenchmarkError> { + let feeder: T::AccountId = whitelisted_caller(); + + #[extrinsic_call] + feed( + RawOrigin::Signed(feeder), + 1.into(), + T::OracleValue::default(), + ); + + Ok(()) + } + + #[benchmark] + fn feed_again() -> Result<(), BenchmarkError> { + let feeder: T::AccountId = whitelisted_caller(); + + Pallet::::feed( + RawOrigin::Signed(feeder.clone()).into(), + 1.into(), + T::OracleValue::default(), + )?; + + #[extrinsic_call] + feed( + RawOrigin::Signed(feeder), + 1.into(), + T::OracleValue::default(), + ); + + Ok(()) + } +} diff --git a/pallets/oracle-feed/src/lib.rs b/pallets/oracle-feed/src/lib.rs index 55b6d07c40..b5e00eefa0 100644 --- a/pallets/oracle-feed/src/lib.rs +++ b/pallets/oracle-feed/src/lib.rs @@ -25,7 +25,13 @@ mod mock; #[cfg(test)] mod tests; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod weights; + pub use pallet::*; +pub use weights::WeightInfo; #[frame_support::pallet] pub mod pallet { @@ -33,6 +39,8 @@ pub mod pallet { use frame_support::{pallet_prelude::*, traits::Time}; use frame_system::pallet_prelude::*; + use crate::weights::WeightInfo; + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); type MomentOf = <::Time as Time>::Moment; @@ -56,6 +64,9 @@ pub mod pallet { /// Fee for the first time a feeder feeds a value type FirstValuePayFee: PayFee; + + /// The weight information for this pallet extrinsics. + type WeightInfo: WeightInfo; } /// Store all oracle values indexed by feeder @@ -90,32 +101,39 @@ pub mod pallet { /// Permissionles call to feed an oracle key from a source with value. /// The first time the value is set, an extra fee is required for the /// feeder. - #[pallet::weight(1_000_000)] + #[pallet::weight(T::WeightInfo::feed_first())] #[pallet::call_index(0)] pub fn feed( origin: OriginFor, key: T::OracleKey, value: T::OracleValue, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; FedValues::::mutate(&who, key, |prev_value| { - if prev_value.is_none() { - T::FirstValuePayFee::pay(&who)?; - } + let new_weight = match prev_value { + None => { + T::FirstValuePayFee::pay(&who)?; + // The weight used is the predefined one. + None + } + Some(_) => { + // The weight used is less than the predefined, + // because we do not need to pay an extra fee + Some(T::WeightInfo::feed_again()) + } + }; *prev_value = Some((value, T::Time::now())); - Ok::<_, DispatchError>(()) - })?; - - Self::deposit_event(Event::::Fed { - account_id: who, - key, - value, - }); + Self::deposit_event(Event::::Fed { + account_id: who.clone(), + key, + value, + }); - Ok(()) + Ok(new_weight.into()) + }) } } diff --git a/pallets/oracle-feed/src/mock.rs b/pallets/oracle-feed/src/mock.rs index c684a97499..9707ae8240 100644 --- a/pallets/oracle-feed/src/mock.rs +++ b/pallets/oracle-feed/src/mock.rs @@ -69,6 +69,7 @@ impl pallet_oracle_feed::Config for Runtime { type OracleValue = OracleValue; type RuntimeEvent = RuntimeEvent; type Time = MockTime; + type WeightInfo = (); } pub fn new_test_ext() -> TestExternalities { diff --git a/pallets/oracle-feed/src/weights.rs b/pallets/oracle-feed/src/weights.rs new file mode 100644 index 0000000000..dff0062838 --- /dev/null +++ b/pallets/oracle-feed/src/weights.rs @@ -0,0 +1,29 @@ +// Copyright 2021 Centrifuge Foundation (centrifuge.io). +// This file is part of Centrifuge chain project. + +// Centrifuge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version (see http://www.gnu.org/licenses). + +// Centrifuge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +use frame_support::weights::Weight; + +pub trait WeightInfo { + fn feed_first() -> Weight; + fn feed_again() -> Weight; +} + +impl WeightInfo for () { + fn feed_first() -> Weight { + Weight::zero() + } + + fn feed_again() -> Weight { + Weight::zero() + } +} diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 2fa97d53b8..e6c665bfb0 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -201,6 +201,8 @@ std = [ "pallet-multisig/std", "pallet-nft/std", "pallet-nft-sales/std", + "pallet-oracle-feed/std", + "pallet-oracle-data-collection/std", "pallet-order-book/std", "pallet-permissions/std", "pallet-pool-registry/std", @@ -277,6 +279,8 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-nft/runtime-benchmarks", "pallet-nft-sales/runtime-benchmarks", + "pallet-oracle-feed/runtime-benchmarks", + "pallet-oracle-data-collection/runtime-benchmarks", "pallet-order-book/runtime-benchmarks", "pallet-permissions/runtime-benchmarks", "pallet-pool-registry/runtime-benchmarks", diff --git a/runtime/development/Cargo.toml b/runtime/development/Cargo.toml index 1dd6a9963c..2e140365af 100644 --- a/runtime/development/Cargo.toml +++ b/runtime/development/Cargo.toml @@ -245,6 +245,8 @@ std = [ "pallet-multisig/std", "pallet-nft/std", "pallet-nft-sales/std", + "pallet-oracle-feed/std", + "pallet-oracle-data-collection/std", "pallet-order-book/std", "pallet-permissions/std", "pallet-pool-registry/std", @@ -331,6 +333,8 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-nft/runtime-benchmarks", "pallet-nft-sales/runtime-benchmarks", + "pallet-oracle-feed/runtime-benchmarks", + "pallet-oracle-data-collection/runtime-benchmarks", "pallet-order-book/runtime-benchmarks", "pallet-permissions/runtime-benchmarks", "pallet-pool-registry/runtime-benchmarks", diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index ff91cc7df0..9f26272509 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -1335,6 +1335,7 @@ impl pallet_oracle_feed::Config for Runtime { type OracleValue = Quantity; type RuntimeEvent = RuntimeEvent; type Time = Timestamp; + type WeightInfo = weights::pallet_oracle_feed::SubstrateWeight; } impl pallet_oracle_data_collection::Config for Runtime { @@ -2650,6 +2651,8 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_liquidity_pools, LiquidityPools); add_benchmark!(params, batches, pallet_nft_sales, NftSales); add_benchmark!(params, batches, pallet_investments, Investments); + add_benchmark!(params, batches, pallet_oracle_feed, OraclePriceFeed); + //add_benchmark!(params, batches, pallet_oracle_data_collection, OraclePriceCollection); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) @@ -2706,6 +2709,8 @@ impl_runtime_apis! { list_benchmark!(list, extra, pallet_liquidity_pools, LiquidityPools); list_benchmark!(list, extra, pallet_nft_sales, NftSales); list_benchmark!(list, extra, pallet_investments, Investments); + list_benchmark!(list, extra, pallet_oracle_feed, OraclePriceFeed); + //list_benchmark!(list, extra, pallet_oracle_data_collection, OraclePriceCollection); let storage_info = AllPalletsWithSystem::storage_info(); diff --git a/runtime/development/src/weights/mod.rs b/runtime/development/src/weights/mod.rs index 8e8e17a2cf..98c078005d 100644 --- a/runtime/development/src/weights/mod.rs +++ b/runtime/development/src/weights/mod.rs @@ -30,6 +30,7 @@ pub mod pallet_loans; pub mod pallet_migration_manager; pub mod pallet_multisig; pub mod pallet_nft_sales; +pub mod pallet_oracle_feed; pub mod pallet_order_book; pub mod pallet_permissions; pub mod pallet_pool_registry; diff --git a/runtime/development/src/weights/pallet_oracle_feed.rs b/runtime/development/src/weights/pallet_oracle_feed.rs new file mode 100644 index 0000000000..63ae874583 --- /dev/null +++ b/runtime/development/src/weights/pallet_oracle_feed.rs @@ -0,0 +1,16 @@ +// TODO: pending to regenerate + +use core::marker::PhantomData; + +use frame_support::weights::Weight; + +pub struct WeightInfo(PhantomData); +impl pallet_investments::WeightInfo for WeightInfo { + fn feed_first() -> Weight { + Weight::zero() + } + + fn feed_again() -> Weight { + Weight::zero() + } +}