This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add storage size component to weights #12277
Merged
Merged
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
f8c395e
Add storage size component to weights
KiChjang 779b815
Rename storage_size to proof_size
KiChjang f7b9346
Update primitives/weights/src/weight_v2.rs
KiChjang 6c84cbd
Fixes
KiChjang 96aa122
cargo fmt
KiChjang 36c2d95
Implement custom Decode and CompactAs
KiChjang 52c9d05
Add missing import
KiChjang 9b1f37e
Fixes
KiChjang 3438ada
Remove CompactAs implementation
KiChjang 3b36396
Properly migrate from 1D weight
KiChjang 7af788c
Remove #[pallet::compact] from Weight parameters
KiChjang f4b98aa
More #[pallet::compact] removals
KiChjang eefc1d7
Add unit tests
KiChjang 109be74
Set appropriate default block proof size
KiChjang bbf072d
cargo fmt
KiChjang 1a07286
Remove nonsensical weight constant
KiChjang 10aed4c
Test only for the reference time weight in frame_system::limits
KiChjang be3d2f6
Only check for reference time weight on idle
KiChjang 20ef5a3
Merge branch 'master' into kckyeung/storage-size-weights
KiChjang 7908713
Use destructuring syntax
KiChjang e313544
Update test expectations
KiChjang 9543674
Merge remote-tracking branch 'origin/master' into kckyeung/storage-si…
KiChjang 91a03b2
Fixes
KiChjang e93dd45
Fixes
KiChjang 9fe54f9
Fixes
KiChjang acd6d4b
Correctly migrate from 1D weights
KiChjang 386d485
cargo fmt
KiChjang e85c05e
Migrate using extra extrinsics instead of custom Decode
KiChjang 470e1bf
Merge remote-tracking branch 'origin/master' into kckyeung/storage-si…
KiChjang f541cb2
Fixes
KiChjang b34b49d
Silence dispatch call warnings that were previously allowed
KiChjang 000ccad
Fix gas_left test
athei 3c4ce94
Use OldWeight instead of u64
KiChjang d3b8a60
Fixes
KiChjang d3e9514
Only check for reference time weight in election provider
KiChjang 4a9f631
Fix test expectations
KiChjang 12b60f8
Fix test expectations
KiChjang b1a9125
Use only reference time weight in grandpa test
KiChjang 3dec18b
Use only reference time weight in examples test
KiChjang 8559428
Use only reference time weight in examples test
KiChjang 4589902
Fix test expectations
KiChjang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -15,7 +15,7 @@ | |
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; | ||
| use codec::{Decode, Encode, MaxEncodedLen}; | ||
| use core::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign}; | ||
| use sp_arithmetic::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; | ||
| use sp_debug_derive::RuntimeDebug; | ||
|
|
@@ -33,12 +33,15 @@ use super::*; | |
| Clone, | ||
| RuntimeDebug, | ||
| Default, | ||
| CompactAs, | ||
| )] | ||
| #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] | ||
| pub struct Weight { | ||
| #[codec(compact)] | ||
| /// The weight of computational time used based on some reference hardware. | ||
| ref_time: u64, | ||
| #[codec(compact)] | ||
| /// The weight of storage space used. | ||
| storage_size: u64, | ||
KiChjang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| impl Weight { | ||
|
|
@@ -48,71 +51,118 @@ impl Weight { | |
| self | ||
| } | ||
|
|
||
| /// Set the storage size part of the weight. | ||
| pub const fn set_storage_size(mut self, c: u64) -> Self { | ||
| self.storage_size = c; | ||
| self | ||
| } | ||
|
|
||
| /// Return the reference time part of the weight. | ||
| pub const fn ref_time(&self) -> u64 { | ||
| self.ref_time | ||
| } | ||
|
|
||
| /// Return a mutable reference time part of the weight. | ||
| /// Return the storage size part of the weight. | ||
| pub const fn storage_size(&self) -> u64 { | ||
| self.storage_size | ||
| } | ||
|
|
||
| /// Return a mutable reference to the reference time part of the weight. | ||
| pub fn ref_time_mut(&mut self) -> &mut u64 { | ||
| &mut self.ref_time | ||
| } | ||
|
|
||
| pub const MAX: Self = Self { ref_time: u64::MAX }; | ||
| /// Return a mutable reference to the storage size part of the weight. | ||
| pub fn storage_size_mut(&mut self) -> &mut u64 { | ||
| &mut self.storage_size | ||
| } | ||
|
|
||
| pub const MAX: Self = Self { ref_time: u64::MAX, storage_size: u64::MAX }; | ||
|
|
||
| /// Get the conservative min of `self` and `other` weight. | ||
| pub fn min(&self, other: Self) -> Self { | ||
| Self { ref_time: self.ref_time.min(other.ref_time) } | ||
| Self { | ||
| ref_time: self.ref_time.min(other.ref_time), | ||
| storage_size: self.storage_size.min(other.storage_size), | ||
| } | ||
| } | ||
|
|
||
| /// Get the aggressive max of `self` and `other` weight. | ||
| pub fn max(&self, other: Self) -> Self { | ||
| Self { ref_time: self.ref_time.max(other.ref_time) } | ||
| Self { | ||
| ref_time: self.ref_time.max(other.ref_time), | ||
| storage_size: self.storage_size.max(other.storage_size), | ||
| } | ||
| } | ||
|
|
||
| /// Try to add some `other` weight while upholding the `limit`. | ||
| pub fn try_add(&self, other: &Self, limit: &Self) -> Option<Self> { | ||
| let total = self.checked_add(other)?; | ||
| if total.ref_time > limit.ref_time { | ||
| if total.ref_time > limit.ref_time || total.storage_size > limit.storage_size { | ||
| None | ||
| } else { | ||
| Some(total) | ||
| } | ||
| } | ||
|
|
||
| /// Construct [`Weight`] with reference time weight. | ||
| /// Construct [`Weight`] with reference time weight and 0 storage size weight. | ||
| pub const fn from_ref_time(ref_time: u64) -> Self { | ||
| Self { ref_time } | ||
| Self { ref_time, storage_size: 0 } | ||
| } | ||
|
|
||
| /// Construct [`Weight`] with storage size weight and 0 reference time weight. | ||
| pub const fn from_storage_size(storage_size: u64) -> Self { | ||
| Self { ref_time: 0, storage_size } | ||
| } | ||
|
|
||
| /// Construct [`Weight`] with weight components, namely reference time and storage size weights. | ||
| pub const fn from_components(ref_time: u64, storage_size: u64) -> Self { | ||
| Self { ref_time, storage_size } | ||
| } | ||
|
|
||
| /// Saturating [`Weight`] addition. Computes `self + rhs`, saturating at the numeric bounds of | ||
| /// all fields instead of overflowing. | ||
| pub const fn saturating_add(self, rhs: Self) -> Self { | ||
| Self { ref_time: self.ref_time.saturating_add(rhs.ref_time) } | ||
| Self { | ||
| ref_time: self.ref_time.saturating_add(rhs.ref_time), | ||
| storage_size: self.storage_size.saturating_add(rhs.storage_size), | ||
| } | ||
| } | ||
|
|
||
| /// Saturating [`Weight`] subtraction. Computes `self - rhs`, saturating at the numeric bounds | ||
| /// of all fields instead of overflowing. | ||
| pub const fn saturating_sub(self, rhs: Self) -> Self { | ||
| Self { ref_time: self.ref_time.saturating_sub(rhs.ref_time) } | ||
| Self { | ||
| ref_time: self.ref_time.saturating_sub(rhs.ref_time), | ||
| storage_size: self.storage_size.saturating_sub(rhs.storage_size), | ||
| } | ||
| } | ||
|
|
||
| /// Saturating [`Weight`] scalar multiplication. Computes `self.field * scalar` for all fields, | ||
| /// saturating at the numeric bounds of all fields instead of overflowing. | ||
| pub const fn saturating_mul(self, scalar: u64) -> Self { | ||
| Self { ref_time: self.ref_time.saturating_mul(scalar) } | ||
| Self { | ||
| ref_time: self.ref_time.saturating_mul(scalar), | ||
| storage_size: self.storage_size.saturating_mul(scalar), | ||
| } | ||
| } | ||
|
|
||
| /// Saturating [`Weight`] scalar division. Computes `self.field / scalar` for all fields, | ||
| /// saturating at the numeric bounds of all fields instead of overflowing. | ||
| pub const fn saturating_div(self, scalar: u64) -> Self { | ||
| Self { ref_time: self.ref_time.saturating_div(scalar) } | ||
| Self { | ||
| ref_time: self.ref_time.saturating_div(scalar), | ||
| storage_size: self.storage_size.saturating_div(scalar), | ||
| } | ||
| } | ||
|
|
||
| /// Saturating [`Weight`] scalar exponentiation. Computes `self.field.pow(exp)` for all fields, | ||
| /// saturating at the numeric bounds of all fields instead of overflowing. | ||
| pub const fn saturating_pow(self, exp: u32) -> Self { | ||
| Self { ref_time: self.ref_time.saturating_pow(exp) } | ||
| Self { | ||
| ref_time: self.ref_time.saturating_pow(exp), | ||
| storage_size: self.storage_size.saturating_pow(exp), | ||
| } | ||
| } | ||
|
|
||
| /// Increment [`Weight`] by `amount` via saturating addition. | ||
|
|
@@ -122,96 +172,116 @@ impl Weight { | |
|
|
||
| /// Checked [`Weight`] addition. Computes `self + rhs`, returning `None` if overflow occurred. | ||
| pub const fn checked_add(&self, rhs: &Self) -> Option<Self> { | ||
| match self.ref_time.checked_add(rhs.ref_time) { | ||
| Some(ref_time) => Some(Self { ref_time }), | ||
| None => None, | ||
| } | ||
| let ref_time = match self.ref_time.checked_add(rhs.ref_time) { | ||
| Some(t) => t, | ||
| None => return None, | ||
| }; | ||
| let storage_size = match self.storage_size.checked_add(rhs.storage_size) { | ||
| Some(s) => s, | ||
| None => return None, | ||
| }; | ||
| Some(Self { ref_time, storage_size }) | ||
| } | ||
|
|
||
| /// Checked [`Weight`] subtraction. Computes `self - rhs`, returning `None` if overflow | ||
| /// occurred. | ||
| pub const fn checked_sub(&self, rhs: &Self) -> Option<Self> { | ||
| match self.ref_time.checked_sub(rhs.ref_time) { | ||
| Some(ref_time) => Some(Self { ref_time }), | ||
| None => None, | ||
| } | ||
| let ref_time = match self.ref_time.checked_sub(rhs.ref_time) { | ||
| Some(t) => t, | ||
| None => return None, | ||
| }; | ||
| let storage_size = match self.storage_size.checked_sub(rhs.storage_size) { | ||
| Some(s) => s, | ||
| None => return None, | ||
| }; | ||
| Some(Self { ref_time, storage_size }) | ||
| } | ||
|
|
||
| /// Checked [`Weight`] scalar multiplication. Computes `self.field * scalar` for each field, | ||
| /// returning `None` if overflow occurred. | ||
| pub const fn checked_mul(self, scalar: u64) -> Option<Self> { | ||
| match self.ref_time.checked_mul(scalar) { | ||
| Some(ref_time) => Some(Self { ref_time }), | ||
| None => None, | ||
| } | ||
| let ref_time = match self.ref_time.checked_mul(scalar) { | ||
| Some(t) => t, | ||
| None => return None, | ||
| }; | ||
| let storage_size = match self.storage_size.checked_mul(scalar) { | ||
| Some(s) => s, | ||
| None => return None, | ||
| }; | ||
| Some(Self { ref_time, storage_size }) | ||
| } | ||
|
|
||
| /// Checked [`Weight`] scalar division. Computes `self.field / scalar` for each field, returning | ||
| /// `None` if overflow occurred. | ||
| pub const fn checked_div(self, scalar: u64) -> Option<Self> { | ||
| match self.ref_time.checked_div(scalar) { | ||
| Some(ref_time) => Some(Self { ref_time }), | ||
| None => None, | ||
| } | ||
| let ref_time = match self.ref_time.checked_div(scalar) { | ||
| Some(t) => t, | ||
| None => return None, | ||
| }; | ||
| let storage_size = match self.storage_size.checked_div(scalar) { | ||
| Some(s) => s, | ||
| None => return None, | ||
| }; | ||
| Some(Self { ref_time, storage_size }) | ||
| } | ||
|
|
||
| /// Return a [`Weight`] where all fields are zero. | ||
| pub const fn zero() -> Self { | ||
| Self { ref_time: 0 } | ||
| Self { ref_time: 0, storage_size: 0 } | ||
| } | ||
|
|
||
| /// Returns true if any of `self`'s constituent weights is strictly greater than that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn any_gt(self, other: Self) -> bool { | ||
| self.ref_time > other.ref_time | ||
| self.ref_time > other.ref_time || self.storage_size > other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if all of `self`'s constituent weights is strictly greater than that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn all_gt(self, other: Self) -> bool { | ||
| self.ref_time > other.ref_time | ||
| self.ref_time > other.ref_time && self.storage_size > other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if any of `self`'s constituent weights is strictly less than that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn any_lt(self, other: Self) -> bool { | ||
| self.ref_time < other.ref_time | ||
| self.ref_time < other.ref_time || self.storage_size < other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if all of `self`'s constituent weights is strictly less than that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn all_lt(self, other: Self) -> bool { | ||
| self.ref_time < other.ref_time | ||
| self.ref_time < other.ref_time && self.storage_size < other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if any of `self`'s constituent weights is greater than or equal to that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn any_gte(self, other: Self) -> bool { | ||
| self.ref_time >= other.ref_time | ||
| self.ref_time >= other.ref_time || self.storage_size >= other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if all of `self`'s constituent weights is greater than or equal to that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn all_gte(self, other: Self) -> bool { | ||
| self.ref_time >= other.ref_time | ||
| self.ref_time >= other.ref_time && self.storage_size >= other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if any of `self`'s constituent weights is less than or equal to that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn any_lte(self, other: Self) -> bool { | ||
| self.ref_time <= other.ref_time | ||
| self.ref_time <= other.ref_time || self.storage_size <= other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if all of `self`'s constituent weights is less than or equal to that of the | ||
| /// `other`'s, otherwise returns false. | ||
| pub const fn all_lte(self, other: Self) -> bool { | ||
| self.ref_time <= other.ref_time | ||
| self.ref_time <= other.ref_time && self.storage_size <= other.storage_size | ||
| } | ||
|
|
||
| /// Returns true if any of `self`'s constituent weights is equal to that of the `other`'s, | ||
| /// otherwise returns false. | ||
| pub const fn any_eq(self, other: Self) -> bool { | ||
| self.ref_time == other.ref_time | ||
| self.ref_time == other.ref_time || self.storage_size == other.storage_size | ||
| } | ||
|
|
||
| // NOTE: `all_eq` does not exist, as it's simply the `eq` method from the `PartialEq` trait. | ||
|
|
@@ -230,14 +300,20 @@ impl Zero for Weight { | |
| impl Add for Weight { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if we could make this
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really unsafe math. |
||
| type Output = Self; | ||
| fn add(self, rhs: Self) -> Self { | ||
| Self { ref_time: self.ref_time + rhs.ref_time } | ||
| Self { | ||
| ref_time: self.ref_time + rhs.ref_time, | ||
| storage_size: self.storage_size + rhs.storage_size, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl Sub for Weight { | ||
| type Output = Self; | ||
| fn sub(self, rhs: Self) -> Self { | ||
| Self { ref_time: self.ref_time - rhs.ref_time } | ||
| Self { | ||
| ref_time: self.ref_time - rhs.ref_time, | ||
| storage_size: self.storage_size - rhs.storage_size, | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -247,7 +323,10 @@ where | |
| { | ||
| type Output = Self; | ||
| fn mul(self, b: T) -> Self { | ||
| Self { ref_time: b * self.ref_time } | ||
| Self { | ||
| ref_time: b * self.ref_time, | ||
| storage_size: b * self.storage_size, | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -257,7 +336,10 @@ macro_rules! weight_mul_per_impl { | |
| impl Mul<Weight> for $t { | ||
| type Output = Weight; | ||
| fn mul(self, b: Weight) -> Weight { | ||
| Weight { ref_time: self * b.ref_time } | ||
| Weight { | ||
| ref_time: self * b.ref_time, | ||
| storage_size: self * b.storage_size, | ||
| } | ||
| } | ||
| } | ||
| )* | ||
|
|
@@ -277,7 +359,10 @@ macro_rules! weight_mul_primitive_impl { | |
| impl Mul<Weight> for $t { | ||
| type Output = Weight; | ||
| fn mul(self, b: Weight) -> Weight { | ||
| Weight { ref_time: u64::from(self) * b.ref_time } | ||
| Weight { | ||
| ref_time: u64::from(self) * b.ref_time, | ||
| storage_size: u64::from(self) * b.storage_size, | ||
| } | ||
| } | ||
| } | ||
| )* | ||
|
|
@@ -292,7 +377,7 @@ where | |
| { | ||
| type Output = Self; | ||
| fn div(self, b: T) -> Self { | ||
| Self { ref_time: self.ref_time / b } | ||
| Self { ref_time: self.ref_time / b, storage_size: self.storage_size / b } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -310,7 +395,7 @@ impl CheckedSub for Weight { | |
|
|
||
| impl core::fmt::Display for Weight { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| write!(f, "Weight(ref_time: {})", self.ref_time) | ||
| write!(f, "Weight(ref_time: {}, storage_size: {})", self.ref_time, self.storage_size) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -325,12 +410,18 @@ impl Bounded for Weight { | |
|
|
||
| impl AddAssign for Weight { | ||
| fn add_assign(&mut self, other: Self) { | ||
| *self = Self { ref_time: self.ref_time + other.ref_time }; | ||
| *self = Self { | ||
| ref_time: self.ref_time + other.ref_time, | ||
| storage_size: self.storage_size + other.storage_size, | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| impl SubAssign for Weight { | ||
| fn sub_assign(&mut self, other: Self) { | ||
| *self = Self { ref_time: self.ref_time - other.ref_time }; | ||
| *self = Self { | ||
| ref_time: self.ref_time - other.ref_time, | ||
| storage_size: self.storage_size - other.storage_size, | ||
| }; | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will need a migration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. but the whole PR will need migration, since weight is now 2-dimensional, so good to have both of these changes in at once.