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

Commit d343bfc

Browse files
authored
Root origin use no filter by default. Scheduler and Democracy dispatch without asserting BaseCallFilter (#6408)
* make system root origin build runtime origin with no filter * additional doc
1 parent a2c493d commit d343bfc

File tree

4 files changed

+55
-10
lines changed

4 files changed

+55
-10
lines changed

frame/democracy/src/tests.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use std::cell::RefCell;
2222
use codec::Encode;
2323
use frame_support::{
2424
impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types,
25-
impl_outer_event, ord_parameter_types, traits::{Contains, OnInitialize}, weights::Weight,
25+
impl_outer_event, ord_parameter_types, traits::{Contains, OnInitialize, Filter},
26+
weights::Weight,
2627
};
2728
use sp_core::H256;
2829
use sp_runtime::{
@@ -74,6 +75,14 @@ impl_outer_event! {
7475
}
7576
}
7677

78+
// Test that a fitlered call can be dispatched.
79+
pub struct BaseFilter;
80+
impl Filter<Call> for BaseFilter {
81+
fn filter(call: &Call) -> bool {
82+
!matches!(call, &Call::Balances(pallet_balances::Call::set_balance(..)))
83+
}
84+
}
85+
7786
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
7887
#[derive(Clone, Eq, PartialEq, Debug)]
7988
pub struct Test;
@@ -84,7 +93,7 @@ parameter_types! {
8493
pub const AvailableBlockRatio: Perbill = Perbill::one();
8594
}
8695
impl frame_system::Trait for Test {
87-
type BaseCallFilter = ();
96+
type BaseCallFilter = BaseFilter;
8897
type Origin = Origin;
8998
type Index = u64;
9099
type BlockNumber = u64;
@@ -225,6 +234,14 @@ fn set_balance_proposal(value: u64) -> Vec<u8> {
225234
Call::Balances(pallet_balances::Call::set_balance(42, value, 0)).encode()
226235
}
227236

237+
#[test]
238+
fn set_balance_proposal_is_correctly_filtered_out() {
239+
for i in 0..10 {
240+
let call = Call::decode(&mut &set_balance_proposal(i)[..]).unwrap();
241+
assert!(!<Test as frame_system::Trait>::BaseCallFilter::filter(&call));
242+
}
243+
}
244+
228245
fn set_balance_proposal_hash(value: u64) -> H256 {
229246
BlakeTwo256::hash(&set_balance_proposal(value)[..])
230247
}

frame/scheduler/src/lib.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ mod tests {
399399

400400
use frame_support::{
401401
impl_outer_event, impl_outer_origin, impl_outer_dispatch, parameter_types, assert_ok,
402-
traits::{OnInitialize, OnFinalize},
402+
traits::{OnInitialize, OnFinalize, Filter},
403403
weights::constants::RocksDbWeight,
404404
};
405405
use sp_core::H256;
@@ -469,6 +469,15 @@ mod tests {
469469
scheduler<T>,
470470
}
471471
}
472+
473+
// Scheduler must dispatch with root and no filter, this tests base filter is indeed not used.
474+
pub struct BaseFilter;
475+
impl Filter<Call> for BaseFilter {
476+
fn filter(call: &Call) -> bool {
477+
!matches!(call, Call::Logger(_))
478+
}
479+
}
480+
472481
// For testing the pallet, we construct most of a mock runtime. This means
473482
// first constructing a configuration type (`Test`) which `impl`s each of the
474483
// configuration traits of pallets we want to use.
@@ -481,7 +490,7 @@ mod tests {
481490
pub const AvailableBlockRatio: Perbill = Perbill::one();
482491
}
483492
impl system::Trait for Test {
484-
type BaseCallFilter = ();
493+
type BaseCallFilter = BaseFilter;
485494
type Origin = Origin;
486495
type Call = Call;
487496
type Index = u64;
@@ -540,7 +549,9 @@ mod tests {
540549
#[test]
541550
fn basic_scheduling_works() {
542551
new_test_ext().execute_with(|| {
543-
Scheduler::do_schedule(4, None, 127, Call::Logger(logger::Call::log(42, 1000)));
552+
let call = Call::Logger(logger::Call::log(42, 1000));
553+
assert!(!<Test as frame_system::Trait>::BaseCallFilter::filter(&call));
554+
Scheduler::do_schedule(4, None, 127, call);
544555
run_to_block(3);
545556
assert!(logger::log().is_empty());
546557
run_to_block(4);

frame/support/src/origin.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ macro_rules! impl_outer_origin {
163163
Modules { };
164164
$( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)*
165165
) => {
166-
// WARNING: All instance must hold the filter `frame_system::Trait::BaseCallFilter`.
167-
// One can use `OriginTrait::reset_filter` to do so.
166+
// WARNING: All instance must hold the filter `frame_system::Trait::BaseCallFilter`, except
167+
// when caller is system Root. One can use `OriginTrait::reset_filter` to do so.
168168
#[derive(Clone)]
169169
pub struct $name {
170170
caller: $caller_name,
@@ -241,28 +241,40 @@ macro_rules! impl_outer_origin {
241241

242242
#[allow(dead_code)]
243243
impl $name {
244+
/// Create with system none origin and `frame-system::Trait::BaseCallFilter`.
244245
pub fn none() -> Self {
245246
$system::RawOrigin::None.into()
246247
}
248+
/// Create with system root origin and no filter.
247249
pub fn root() -> Self {
248250
$system::RawOrigin::Root.into()
249251
}
252+
/// Create with system signed origin and `frame-system::Trait::BaseCallFilter`.
250253
pub fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self {
251254
$system::RawOrigin::Signed(by).into()
252255
}
253256
}
254257

255258
impl From<$system::Origin<$runtime>> for $name {
259+
/// Convert to runtime origin:
260+
/// * root origin is built with no filter
261+
/// * others use `frame-system::Trait::BaseCallFilter`
256262
fn from(x: $system::Origin<$runtime>) -> Self {
257263
let mut o = $name {
258264
caller: $caller_name::system(x),
259265
filter: $crate::sp_std::rc::Rc::new(Box::new(|_| true)),
260266
};
261-
$crate::traits::OriginTrait::reset_filter(&mut o);
267+
268+
// Root has no filter
269+
if !matches!(o.caller, $caller_name::system($system::Origin::<$runtime>::Root)) {
270+
$crate::traits::OriginTrait::reset_filter(&mut o);
271+
}
272+
262273
o
263274
}
264275
}
265276
impl Into<$crate::sp_std::result::Result<$system::Origin<$runtime>, $name>> for $name {
277+
/// NOTE: converting to pallet origin loses the origin filter information.
266278
fn into(self) -> $crate::sp_std::result::Result<$system::Origin<$runtime>, Self> {
267279
if let $caller_name::system(l) = self.caller {
268280
Ok(l)
@@ -272,13 +284,16 @@ macro_rules! impl_outer_origin {
272284
}
273285
}
274286
impl From<Option<<$runtime as $system::Trait>::AccountId>> for $name {
287+
/// Convert to runtime origin with caller being system signed or none and use filter
288+
/// `frame-system::Trait::BaseCallFilter`.
275289
fn from(x: Option<<$runtime as $system::Trait>::AccountId>) -> Self {
276290
<$system::Origin<$runtime>>::from(x).into()
277291
}
278292
}
279293
$(
280294
$crate::paste::item! {
281295
impl From<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > for $name {
296+
/// Convert to runtime origin using `frame-system::Trait::BaseCallFilter`.
282297
fn from(x: $module::Origin < $( $generic )? $(, $module::$generic_instance )? >) -> Self {
283298
let mut o = $name {
284299
caller: $caller_name::[< $module $( _ $generic_instance )? >](x),
@@ -294,6 +309,7 @@ macro_rules! impl_outer_origin {
294309
$name,
295310
>>
296311
for $name {
312+
/// NOTE: converting to pallet origin loses the origin filter information.
297313
fn into(self) -> $crate::sp_std::result::Result<
298314
$module::Origin < $( $generic )? $(, $module::$generic_instance )? >,
299315
Self,
@@ -402,7 +418,7 @@ mod tests {
402418
#[test]
403419
fn test_default_filter() {
404420
assert_eq!(OriginWithSystem::root().filter_call(&0), true);
405-
assert_eq!(OriginWithSystem::root().filter_call(&1), false);
421+
assert_eq!(OriginWithSystem::root().filter_call(&1), true);
406422
assert_eq!(OriginWithSystem::none().filter_call(&0), true);
407423
assert_eq!(OriginWithSystem::none().filter_call(&1), false);
408424
assert_eq!(OriginWithSystem::signed(0).filter_call(&0), true);

frame/system/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>) -> H::Output {
149149
}
150150

151151
pub trait Trait: 'static + Eq + Clone {
152-
/// The basic call filter to use in Origin.
152+
/// The basic call filter to use in Origin. All origins are built with this filter as base,
153+
/// except Root.
153154
type BaseCallFilter: Filter<Self::Call>;
154155

155156
/// The `Origin` type used by dispatchable calls.

0 commit comments

Comments
 (0)