-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CheckWeight: account for extrinsic len as proof size #4765
Conversation
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
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.
Looks sensible.
let extrinsic_weight = info | ||
.weight | ||
.saturating_add(maximum_weight.get(info.class).base_extrinsic) | ||
.saturating_add(Weight::from_parts(0, len as u64)); |
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.
Stupid question: Is this also used for inherents? (Does this have any influence on weights on the relaychain as relevant to parachain consensus?)
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.
Specifically: We already add lengths to the weight in paras inherent for checking within the paras inherent to not exceed the weight e.g. here. I hope we are not counting it twice now?
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.
I don't understand what is the reasoning is for this. Why are we setting the proof size there? On relay chains the maximum proof size is U64::MAX
AFAIK, effectively disabling any proof size related checks.
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.
Good point @skunert . I think we should remove and clean the code in parachain inherent. Proof size is indeed only relevant for parachain runtimes.
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.
Do we not need this excape hatch for the Mandatory inherents to avoid what happend on the rococo parachains?
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.
What happened on Rococo parachains ?
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.
It got stuck because an inherent ran a lazy migration that loaded a big Key pair and overflowed the PoV limit.
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.
@ggwpez Sorry for the late reply, I thought about the rococo situation before approval here.
So we don't have an explicit mechanism for mandatory extrinsics here because we will go into these two branches dring the weight checks:
- This one because for mandatory
max_total
isNone
:_ => {}, - This one because reserved is also
None
for mandatory extrinsics:polkadot-sdk/substrate/frame/system/src/extensions/check_weight.rs
Lines 222 to 224 in 0bb931b
// There is either no limit in reserved pool (`None`), // or we are below the limit. _ => {},
Of course what I described above is not guaranteed. Parachain teams can define in their runtime whatever they want. This is what the typical weight definition looks like (note no specifics defined for mandatory):
polkadot-sdk/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Lines 138 to 155 in 0bb931b
pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() | |
.base_block(BlockExecutionWeight::get()) | |
.for_class(DispatchClass::all(), |weights| { | |
weights.base_extrinsic = ExtrinsicBaseWeight::get(); | |
}) | |
.for_class(DispatchClass::Normal, |weights| { | |
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); | |
}) | |
.for_class(DispatchClass::Operational, |weights| { | |
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); | |
// Operational transactions have some extra reserved space, so that they | |
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. | |
weights.reserved = Some( | |
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT | |
); | |
}) | |
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) | |
.build_or_panic(); |
The builder has None
set by default, which makes sense:
polkadot-sdk/substrate/frame/system/src/limits.rs
Lines 347 to 354 in 0bb931b
let initial = | |
if class == DispatchClass::Mandatory { None } else { Some(Weight::zero()) }; | |
WeightsPerClass { | |
base_extrinsic: constants::ExtrinsicBaseWeight::get(), | |
max_extrinsic: None, | |
max_total: initial, | |
reserved: initial, | |
} |
So with this PR the weight checking falls in line with the rest of the extrinsics. If someone has actually set a limit on mandatory weight class, they are living dangerous without the changes of this PR already. If some pallet returns max weight like the session pallet in the rococo case, we would already go over the limit together with on_initialize
.
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.
Okay i see. Thanks for the elaborate explanation!
This reverts commit 2211d15. Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
The CI pipeline was cancelled due to failure one of the required jobs. |
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
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.
Looks good, thank you!
Glutton currently is useful mostly for stress testing relay chain validators. It is unusable for testing the collator networking and block announcement and import scenarios. This PR resolves that by improving glutton pallet to also buff up the blocks, up to the runtime configured `BlockLength`. ### How it works Includes an additional inherent in each parachain block. The `garbage` argument passed to the inherent is filled with trash data. It's size is computed by applying the newly introduced `block_length` percentage to the maximum block length for mandatory dispatch class. After #4765 is merged, the length of inherent extrinsic will be added to the total block proof size. The remaining weight is burnt in `on_idle` as configured by the `storage` percentage parameter. TODO: - [x] PRDoc - [x] Readme update - [x] Add tests --------- Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Fix paritytech#4743 which allows us to remove the defensive limit on pov size in Cumulus after relay chain gets upgraded with these changes. Also add unit test to ensure `CheckWeight` - `StorageWeightReclaim` integration works. TODO: - [x] PRDoc - [x] Add a len to all the other tests in storage weight reclaim and call `CheckWeight::pre_dispatch` --------- Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Glutton currently is useful mostly for stress testing relay chain validators. It is unusable for testing the collator networking and block announcement and import scenarios. This PR resolves that by improving glutton pallet to also buff up the blocks, up to the runtime configured `BlockLength`. ### How it works Includes an additional inherent in each parachain block. The `garbage` argument passed to the inherent is filled with trash data. It's size is computed by applying the newly introduced `block_length` percentage to the maximum block length for mandatory dispatch class. After paritytech#4765 is merged, the length of inherent extrinsic will be added to the total block proof size. The remaining weight is burnt in `on_idle` as configured by the `storage` percentage parameter. TODO: - [x] PRDoc - [x] Readme update - [x] Add tests --------- Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>
Fix #4743 which allows us to remove the defensive limit on pov size in Cumulus after relay chain gets upgraded with these changes. Also add unit test to ensure
CheckWeight
-StorageWeightReclaim
integration works.TODO:
CheckWeight::pre_dispatch