Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Update System Weights #5888

Merged
merged 28 commits into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2b575d7
Update system weights
shawntabrizi May 4, 2020
fa7fed1
Use maximum block weight for scheduler
shawntabrizi May 5, 2020
0bbe0ce
Update offences to use full block
shawntabrizi May 5, 2020
87277d0
Move weight inside if statement
shawntabrizi May 5, 2020
7df7ebc
Add one read to offences `on_initialize`
shawntabrizi May 5, 2020
8f95aac
Delete factory test
shawntabrizi May 5, 2020
2dd84b0
Revert "Delete factory test"
shawntabrizi May 5, 2020
6e2bf91
Revert "Add one read to offences `on_initialize`"
shawntabrizi May 5, 2020
65a29a8
Revert "Move weight inside if statement"
shawntabrizi May 5, 2020
820aa6e
Revert "Update offences to use full block"
shawntabrizi May 5, 2020
95bd276
Use scheduler in Sudo
shawntabrizi May 5, 2020
b48d9b1
Apply suggestions from code review
shawntabrizi May 5, 2020
e875f5d
Revert "Use scheduler in Sudo"
shawntabrizi May 5, 2020
edd5196
remove max extrinsic weight (it does nothing useful)
shawntabrizi May 5, 2020
45f4c26
fix tests
shawntabrizi May 5, 2020
eb986b2
introduce `sudo_unchecked_weight`
shawntabrizi May 5, 2020
8357736
Merge branch 'master' into shawntabrizi-system-weight
shawntabrizi May 5, 2020
45009c4
bump spec version
shawntabrizi May 5, 2020
47418e8
Merge branch 'master' into shawntabrizi-system-weight
shawntabrizi May 6, 2020
112aae0
Merge branch 'master' into shawntabrizi-system-weight
shawntabrizi May 6, 2020
32e86c9
scheduler 80 percent of maximum
shawntabrizi May 6, 2020
db15aaa
Update `set_changes_trie_config` weight
shawntabrizi May 6, 2020
5d582da
Merge branch 'master' into shawntabrizi-system-weight
shawntabrizi May 6, 2020
dea831a
Update bin/node/runtime/src/lib.rs
shawntabrizi May 6, 2020
15f8ad2
Update frame/democracy/src/tests.rs
shawntabrizi May 6, 2020
2593595
Update tests.rs
shawntabrizi May 6, 2020
f1bdc7e
update based on feedback
shawntabrizi May 7, 2020
86c826e
Merge branch 'master' into shawntabrizi-system-weight
shawntabrizi May 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl pallet_utility::Trait for Runtime {
}

parameter_types! {
pub const MaximumWeight: Weight = 2_000_000;
pub const MaximumWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get();
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
}

impl pallet_scheduler::Trait for Runtime {
Expand Down
2 changes: 1 addition & 1 deletion frame/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ decl_module! {
}

/// Enact a proposal from a referendum. For now we just make the weight be the maximum.
#[weight = frame_system::Module::<T>::max_extrinsic_weight(DispatchClass::Normal)]
#[weight = T::MaximumBlockWeight::get()]
athei marked this conversation as resolved.
Show resolved Hide resolved
fn enact_proposal(origin, proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult {
ensure_root(origin)?;
Self::do_enact_proposal(proposal_hash, index)
Expand Down
8 changes: 5 additions & 3 deletions frame/democracy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl_outer_event! {
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockWeight: Weight = 1_000_000;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
}
Expand Down Expand Up @@ -106,15 +106,17 @@ impl frame_system::Trait for Test {
type OnKilledAccount = ();
}
parameter_types! {
pub const ExistentialDeposit: u64 = 1;
pub const MaximumWeight: u32 = 1000000;
pub const MaximumWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get();
}
impl pallet_scheduler::Trait for Test {
type Event = Event;
type Origin = Origin;
type Call = Call;
type MaximumWeight = MaximumWeight;
}
parameter_types! {
pub const ExistentialDeposit: u64 = 1;
}
impl pallet_balances::Trait for Test {
type Balance = u64;
type Event = Event;
Expand Down
5 changes: 3 additions & 2 deletions frame/scheduler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ mod tests {
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockWeight: Weight = 12_500;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
}
Expand Down Expand Up @@ -363,7 +363,8 @@ mod tests {
type Event = ();
}
parameter_types! {
pub const MaximumWeight: Weight = 10_000;
// 10_000
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
pub const MaximumWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get();
}
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
impl Trait for Test {
type Event = ();
Expand Down
26 changes: 25 additions & 1 deletion frame/sudo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ use sp_runtime::{DispatchResult, traits::{StaticLookup, Dispatchable}};
use frame_support::{
Parameter, decl_module, decl_event, decl_storage, decl_error, ensure,
};
use frame_support::weights::{GetDispatchInfo, FunctionOf, Pays};
use frame_support::weights::{Weight, GetDispatchInfo, FunctionOf, Pays};
use frame_system::{self as system, ensure_signed};

pub trait Trait: frame_system::Trait {
Expand Down Expand Up @@ -134,6 +134,30 @@ decl_module! {
Self::deposit_event(RawEvent::Sudid(res.map(|_| ()).map_err(|e| e.error)));
}

/// Authenticates the sudo key and dispatches a function call with `Root` origin.
/// This function does not check the weight of the call, and instead allows the
/// Sudo user to specify the weight of the call.
///
/// The dispatch origin for this call must be _Signed_.
///
/// # <weight>
/// - O(1).
/// - The weight of this call is defined by the caller.
/// # </weight>
#[weight = FunctionOf(
|(_, &weight): (&Box<<T as Trait>::Call>,&Weight,)| weight,
|(call, _): (&Box<<T as Trait>::Call>,&Weight,)| call.get_dispatch_info().class,
Pays::Yes,
)]
fn sudo_unchecked_weight(origin, call: Box<<T as Trait>::Call>, _weight: Weight) {
athei marked this conversation as resolved.
Show resolved Hide resolved
// This is a public call, so we ensure that the origin is some signed account.
let sender = ensure_signed(origin)?;
ensure!(sender == Self::key(), Error::<T>::RequireSudo);

let res = call.dispatch(frame_system::RawOrigin::Root.into());
Self::deposit_event(RawEvent::Sudid(res.map(|_| ()).map_err(|e| e.error)));
}

/// Authenticates the current sudo key and sets the given AccountId (`new`) as the new sudo key.
///
/// The dispatch origin for this call must be _Signed_.
Expand Down
2 changes: 1 addition & 1 deletion frame/system/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ benchmarks! {
let value = storage::unhashed::get_raw(&last_key).ok_or("No value stored")?;
assert_eq!(value, last_key);

}: _(RawOrigin::Root, prefix)
}: _(RawOrigin::Root, prefix, p)
verify {
assert_eq!(storage::unhashed::get_raw(&last_key), None);
}
Expand Down
136 changes: 61 additions & 75 deletions frame/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,10 @@ decl_module! {
///
/// # <weight>
/// - `O(1)`
/// - Base Weight: 0.665 µs, independent of remark length.
/// - No DB operations.
/// # </weight>
#[weight = 0]
#[weight = 700_000]
fn remark(origin, _remark: Vec<u8>) {
ensure_signed(origin)?;
}
Expand All @@ -523,8 +525,10 @@ decl_module! {
/// # <weight>
/// - `O(1)`
/// - 1 storage write.
/// - Base Weight: 1.405 µs
/// - 1 write to HEAP_PAGES
/// # </weight>
#[weight = (0, DispatchClass::Operational)]
#[weight = (T::DbWeight::get().writes(1) + 1_500_000, DispatchClass::Operational)]
fn set_heap_pages(origin, pages: u64) {
ensure_root(origin)?;
storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
Expand All @@ -537,8 +541,10 @@ decl_module! {
/// - 1 storage write (codec `O(C)`).
/// - 1 call to `can_set_code`: `O(S)` (calls `sp_io::misc::runtime_version` which is expensive).
/// - 1 event.
/// The weight of this function is dependent on the runtime, but generally this is very expensive.
/// We will treat this as a full block.
/// # </weight>
#[weight = (200_000_000, DispatchClass::Operational)]
#[weight = (T::MaximumBlockWeight::get(), DispatchClass::Operational)]
pub fn set_code(origin, code: Vec<u8>) {
Self::can_set_code(origin, &code)?;

Expand All @@ -552,8 +558,9 @@ decl_module! {
/// - `O(C)` where `C` length of `code`
/// - 1 storage write (codec `O(C)`).
/// - 1 event.
/// The weight of this function is dependent on the runtime. We will treat this as a full block.
/// # </weight>
#[weight = (200_000_000, DispatchClass::Operational)]
#[weight = (T::MaximumBlockWeight::get(), DispatchClass::Operational)]
pub fn set_code_without_checks(origin, code: Vec<u8>) {
ensure_root(origin)?;
storage::unhashed::put_raw(well_known_keys::CODE, &code);
Expand All @@ -566,8 +573,11 @@ decl_module! {
/// - `O(D)` where `D` length of `Digest`
/// - 1 storage write or delete (codec `O(1)`).
/// - 1 call to `deposit_log`: `O(D)` (which depends on the length of `Digest`)
/// - Base Weight: 7.218 + 0.001 * D µs
/// - DB Weight:
/// - Writes: Changes Trie, System Digest
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
/// # </weight>
#[weight = (20_000_000, DispatchClass::Operational)]
#[weight = (T::DbWeight::get().writes(2) + 10_000_000, DispatchClass::Operational)]
pub fn set_changes_trie_config(origin, changes_trie_config: Option<ChangesTrieConfiguration>) {
ensure_root(origin)?;
match changes_trie_config.clone() {
Expand All @@ -589,8 +599,17 @@ decl_module! {
/// # <weight>
/// - `O(I)` where `I` length of `items`
/// - `I` storage writes (`O(1)`).
/// - Base Weight: 0.568 * i
/// - Writes: Number of items
/// # </weight>
#[weight = (0, DispatchClass::Operational)]
#[weight = FunctionOf(
|(items,): (&Vec<KeyValue>,)| {
T::DbWeight::get().writes(items.len() as Weight)
.saturating_add((items.len() as Weight).saturating_mul(600_000))
},
DispatchClass::Operational,
Pays::Yes,
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
)]
fn set_storage(origin, items: Vec<KeyValue>) {
ensure_root(origin)?;
for i in &items {
Expand All @@ -601,10 +620,19 @@ decl_module! {
/// Kill some items from storage.
///
/// # <weight>
/// - `O(VK)` where `V` length of `keys` and `K` length of one key
/// - `V` storage deletions.
/// - `O(IK)` where `I` length of `keys` and `K` length of one key
/// - `I` storage deletions.
/// - Base Weight: .378 * i µs
/// - Writes: Number of items
/// # </weight>
#[weight = (0, DispatchClass::Operational)]
#[weight = FunctionOf(
|(keys,): (&Vec<Key>,)| {
T::DbWeight::get().writes(keys.len() as Weight)
.saturating_add((keys.len() as Weight).saturating_mul(400_000))
},
DispatchClass::Operational,
Pays::Yes,
)]
fn kill_storage(origin, keys: Vec<Key>) {
ensure_root(origin)?;
for key in &keys {
Expand All @@ -614,12 +642,24 @@ decl_module! {

/// Kill all storage items with a key that starts with the given prefix.
///
/// **NOTE:** We rely on the Root origin to provide us the number of subkeys under
/// the prefix we are removing to accurately calculate the weight of this function.
///
/// # <weight>
/// - `O(P)` where `P` amount of keys with prefix `prefix`
/// - `P` storage deletions.
/// - Base Weight: 0.834 * P µs
/// - Writes: Number of subkeys + 1
/// # </weight>
#[weight = (0, DispatchClass::Operational)]
fn kill_prefix(origin, prefix: Key) {
#[weight = FunctionOf(
|(_, &subkeys): (&Key, &u32)| {
T::DbWeight::get().writes(Weight::from(subkeys) + 1)
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
.saturating_add((Weight::from(subkeys) + 1).saturating_mul(850_000))
},
DispatchClass::Operational,
Pays::Yes,
)]
fn kill_prefix(origin, prefix: Key, _subkeys: u32) {
ensure_root(origin)?;
storage::unhashed::kill_prefix(&prefix);
}
Expand All @@ -630,8 +670,11 @@ decl_module! {
/// # <weight>
/// - `O(1)`
/// - 1 storage read and deletion.
/// --------------------
/// Base Weight: 8.626 µs
/// No DB Read or Write operations because caller is already in overlay
/// # </weight>
#[weight = (25_000_000, DispatchClass::Operational)]
#[weight = (10_000_000, DispatchClass::Operational)]
fn suicide(origin) {
let who = ensure_signed(origin)?;
let account = Account::<T>::get(&who);
Expand Down Expand Up @@ -874,23 +917,6 @@ impl<T: Trait> Module<T> {
AllExtrinsicsWeight::get().unwrap_or_default()
}

/// Get the quota ratio of each dispatch class type. This indicates that all operational and mandatory
/// dispatches can use the full capacity of any resource, while user-triggered ones can consume
/// a portion.
pub fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill {
match class {
DispatchClass::Operational | DispatchClass::Mandatory
=> <Perbill as sp_runtime::PerThing>::one(),
DispatchClass::Normal => T::AvailableBlockRatio::get(),
}
}

/// The maximum weight of an allowable extrinsic. Only one of these could exist in a block.
pub fn max_extrinsic_weight(class: DispatchClass) -> Weight {
let limit = Self::get_dispatch_limit_ratio(class) * T::MaximumBlockWeight::get();
limit - (T::BlockExecutionWeight::get() + T::ExtrinsicBaseWeight::get())
}

pub fn all_extrinsics_len() -> u32 {
AllExtrinsicsLen::get().unwrap_or_default()
}
Expand Down Expand Up @@ -1257,7 +1283,11 @@ impl<T: Trait + Send + Sync> CheckWeight<T> where
/// dispatches can use the full capacity of any resource, while user-triggered ones can consume
/// a portion.
fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill {
Module::<T>::get_dispatch_limit_ratio(class)
match class {
DispatchClass::Operational | DispatchClass::Mandatory
=> <Perbill as sp_runtime::PerThing>::one(),
DispatchClass::Normal => T::AvailableBlockRatio::get(),
}
}

/// Checks if the current extrinsic can fit into the block with respect to block weight limits.
Expand Down Expand Up @@ -1680,7 +1710,7 @@ pub(crate) mod tests {
use sp_std::cell::RefCell;
use sp_core::H256;
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup, SignedExtension}, testing::Header, DispatchError};
use frame_support::{impl_outer_origin, parameter_types, assert_ok, assert_err};
use frame_support::{impl_outer_origin, parameter_types, assert_ok};

impl_outer_origin! {
pub enum Origin for Test where system = super {}
Expand Down Expand Up @@ -2082,47 +2112,6 @@ pub(crate) mod tests {
})
}

#[test]
fn max_extrinsic_weight_is_allowed_but_nothing_more() {
// Dispatch Class Normal
new_test_ext().execute_with(|| {
let one = DispatchInfo { weight: 1, ..Default::default() };
let max = DispatchInfo { weight: System::max_extrinsic_weight(DispatchClass::Normal), ..Default::default() };
let len = 0_usize;

assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&max, len));
assert_err!(
CheckWeight::<Test>::do_pre_dispatch(&one, len),
InvalidTransaction::ExhaustsResources,
);
// Weight should be 75% of 1024 (max block weight)
assert_eq!(System::all_extrinsics_weight(), 768);
});

// Dispatch Class Operational
new_test_ext().execute_with(|| {
let one = DispatchInfo {
weight: 1,
class: DispatchClass::Operational,
..Default::default()
};
let max = DispatchInfo {
weight: System::max_extrinsic_weight(DispatchClass::Operational),
class: DispatchClass::Operational,
..Default::default()
};
let len = 0_usize;

assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&max, len));
assert_err!(
CheckWeight::<Test>::do_pre_dispatch(&one, len),
InvalidTransaction::ExhaustsResources,
);
// Weight should be 100% of max block weight
assert_eq!(System::all_extrinsics_weight(), <Test as Trait>::MaximumBlockWeight::get());
});
}

#[test]
fn mandatory_extrinsic_doesnt_care_about_limits() {
new_test_ext().execute_with(|| {
Expand Down Expand Up @@ -2156,9 +2145,6 @@ pub(crate) mod tests {
// 10 is taken for block execution weight
// So normal extrinsic can be 758 weight (-5 for base extrinsic weight)
// And Operational can be 256 to produce a full block (-5 for base)

assert_eq!(System::max_extrinsic_weight(DispatchClass::Normal), 753);

let max_normal = DispatchInfo { weight: 753, ..Default::default() };
let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() };

Expand Down