pallet-scheduler: Introduce OriginPrivilegeCmp (#10078)

* pallet-scheduler: Introduce `OriginPrivilegeCmp`

When a scheduled task should be canceled, the origin that tries to
cancel the task is compared to the origin the task should be executed
with. Before this pr this check only allowed that both origins are
equal. However, this is problematic as this means that for example a
council origin it needs to be have the same amount of yes votes to
cancel the scheduled task. While a council origin with more yes votes
should be able to cancel this task. This happened recently on Kusama and
lead to a failed cancelation of a scheduled task. With this pr the two
origins are compared and the cancelling origin needs to have greater or
equal privileges as the origin that scheduled the task. What a greater,
equal or less privilege is, can be configured in the runtime.

For simplicity, a `EqualPrivilegeOnly` implementation is provided that
only checks if two origins are equal. So, this mimics the old behaviour.

* FMT

* fix import

* Small optimizations

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Bastian Köcher
2021-10-29 18:00:49 +02:00
committed by GitHub
parent c30233ab13
commit 95b8fd61c3
5 changed files with 51 additions and 13 deletions
+21 -1
View File
@@ -21,7 +21,7 @@ use crate::dispatch::Parameter;
use codec::{CompactLen, Decode, DecodeAll, Encode, EncodeLike, Input, MaxEncodedLen};
use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter};
use sp_runtime::{traits::Block as BlockT, DispatchError};
use sp_std::prelude::*;
use sp_std::{cmp::Ordering, prelude::*};
/// Anything that can have a `::len()` method.
pub trait Len {
@@ -289,6 +289,26 @@ pub trait ExecuteBlock<Block: BlockT> {
fn execute_block(block: Block);
}
/// Something that can compare privileges of two origins.
pub trait PrivilegeCmp<Origin> {
/// Compare the `left` to the `right` origin.
///
/// The returned ordering should be from the pov of the `left` origin.
///
/// Should return `None` when it can not compare the given origins.
fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering>;
}
/// Implementation of [`PrivilegeCmp`] that only checks for equal origins.
///
/// This means it will either return [`Origin::Equal`] or `None`.
pub struct EqualPrivilegeOnly;
impl<Origin: PartialEq> PrivilegeCmp<Origin> for EqualPrivilegeOnly {
fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering> {
(left == right).then(|| Ordering::Equal)
}
}
/// Off-chain computation trait.
///
/// Implementing this trait on a module allows you to perform long-running tasks