Skip to content
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

Add defensive testing extrinsic #1998

Merged
merged 12 commits into from
Oct 31, 2023
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion polkadot/runtime/rococo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pallet-scheduler = { path = "../../../substrate/frame/scheduler", default-featur
pallet-session = { path = "../../../substrate/frame/session", default-features = false }
pallet-society = { path = "../../../substrate/frame/society", default-features = false, features = ["experimental"] }
pallet-sudo = { path = "../../../substrate/frame/sudo", default-features = false }
frame-support = { path = "../../../substrate/frame/support", default-features = false }
frame-support = { path = "../../../substrate/frame/support", default-features = false, features = ["tuples-96"] }
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
pallet-staking = { path = "../../../substrate/frame/staking", default-features = false }
frame-system = { path = "../../../substrate/frame/system", default-features = false }
frame-system-rpc-runtime-api = { path = "../../../substrate/frame/system/rpc/runtime-api", default-features = false }
Expand All @@ -78,6 +78,7 @@ pallet-utility = { path = "../../../substrate/frame/utility", default-features =
pallet-vesting = { path = "../../../substrate/frame/vesting", default-features = false }
pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false, features=["experimental"] }
pallet-xcm-benchmarks = { path = "../../xcm/pallet-xcm-benchmarks", default-features = false, optional = true }
pallet-root-testing = { path = "../../../substrate/frame/root-testing", default-features = false }

frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true }
frame-try-runtime = { path = "../../../substrate/frame/try-runtime", default-features = false, optional = true }
Expand Down Expand Up @@ -146,6 +147,7 @@ std = [
"pallet-preimage/std",
"pallet-proxy/std",
"pallet-recovery/std",
"pallet-root-testing/std",
"pallet-scheduler/std",
"pallet-session/std",
"pallet-society/std",
Expand Down Expand Up @@ -251,6 +253,7 @@ try-runtime = [
"pallet-preimage/try-runtime",
"pallet-proxy/try-runtime",
"pallet-recovery/try-runtime",
"pallet-root-testing/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-session/try-runtime",
"pallet-society/try-runtime",
Expand Down
7 changes: 7 additions & 0 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,10 @@ impl pallet_sudo::Config for Runtime {
type WeightInfo = weights::pallet_sudo::WeightInfo<Runtime>;
}

impl pallet_root_testing::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}

construct_runtime! {
pub enum Runtime
{
Expand Down Expand Up @@ -1502,6 +1506,9 @@ construct_runtime! {
// State trie migration pallet, only temporary.
StateTrieMigration: pallet_state_trie_migration = 254,

// Root testing pallet.
RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event<T>} = 249,

// Sudo.
Sudo: pallet_sudo::{Pallet, Call, Storage, Event<T>, Config<T>} = 255,
}
Expand Down
3 changes: 3 additions & 0 deletions polkadot/runtime/westend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pallet-utility = { path = "../../../substrate/frame/utility", default-features =
pallet-vesting = { path = "../../../substrate/frame/vesting", default-features = false }
pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false, features=["experimental"] }
pallet-xcm-benchmarks = { path = "../../xcm/pallet-xcm-benchmarks", default-features = false, optional = true }
pallet-root-testing = { path = "../../../substrate/frame/root-testing", default-features = false }

frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true }
frame-try-runtime = { path = "../../../substrate/frame/try-runtime", default-features = false, optional = true }
Expand Down Expand Up @@ -161,6 +162,7 @@ std = [
"pallet-preimage/std",
"pallet-proxy/std",
"pallet-recovery/std",
"pallet-root-testing/std",
"pallet-scheduler/std",
"pallet-session/std",
"pallet-society/std",
Expand Down Expand Up @@ -274,6 +276,7 @@ try-runtime = [
"pallet-preimage/try-runtime",
"pallet-proxy/try-runtime",
"pallet-recovery/try-runtime",
"pallet-root-testing/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-session/try-runtime",
"pallet-society/try-runtime",
Expand Down
6 changes: 6 additions & 0 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,10 @@ impl pallet_nomination_pools::Config for Runtime {
type MaxPointsToBalance = MaxPointsToBalance;
}

impl pallet_root_testing::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}

parameter_types! {
// The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high)
pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS;
Expand Down Expand Up @@ -1364,6 +1368,8 @@ construct_runtime! {

// Generalized message queue
MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 100,

RootTesting: pallet_root_testing = 101,
}
}

Expand Down
24 changes: 21 additions & 3 deletions substrate/frame/root-testing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@

#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::dispatch::DispatchResult;
use sp_runtime::Perbill;
use frame_support::{dispatch::DispatchResult, sp_runtime::Perbill};

pub use pallet::*;

Expand All @@ -36,11 +35,21 @@ pub mod pallet {
use frame_system::pallet_prelude::*;

#[pallet::config]
pub trait Config: frame_system::Config {}
pub trait Config: frame_system::Config {
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Event dispatched when the trigger_defensive extrinsic is called.
DefensiveTestCall,
}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// A dispatch that will fill the block weight up to the given ratio.
Expand All @@ -50,5 +59,14 @@ pub mod pallet {
ensure_root(origin)?;
Ok(())
}

#[pallet::call_index(1)]
#[pallet::weight(0)]
pub fn trigger_defensive(origin: OriginFor<T>) -> DispatchResult {
ensure_root(origin)?;
frame_support::defensive!("root_testing::trigger_defensive was called.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggwpez so you want this to panic? I don't really get what you want to achieve?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defensive is just log error and debug_assert, which is nop on release build, so this is a bit pointless. if you want to test log error, just log error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I know that this is using a debug assert, I was assuming @ggwpez wants to build with debug asserts enabled and then use it as overwrite.

Copy link
Member

@ggwpez ggwpez Oct 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea here is that we are currently not sure if the monitoring correctly picks up defensive failures. And we really should be notified about them, so this is just as test.
It could also be logged, but the defensive! macro also logs a magic string (DEFENSIVE_OP_PUBLIC_ERROR) that we can filter for and alert in the grafana.
Then we can call this and check that we got notifications in chat about this failure.

Self::deposit_event(Event::DefensiveTestCall);
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}
}
}
6 changes: 3 additions & 3 deletions substrate/frame/support/src/traits/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ pub const DEFENSIVE_OP_INTERNAL_ERROR: &str = "Defensive failure has been trigge
macro_rules! defensive {
() => {
frame_support::__private::log::error!(
target: "runtime",
target: "runtime::defensive",
"{}",
$crate::traits::DEFENSIVE_OP_PUBLIC_ERROR
);
debug_assert!(false, "{}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR);
};
($error:expr $(,)?) => {
frame_support::__private::log::error!(
target: "runtime",
target: "runtime::defensive",
"{}: {:?}",
$crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
$error
Expand All @@ -60,7 +60,7 @@ macro_rules! defensive {
};
($error:expr, $proof:expr $(,)?) => {
frame_support::__private::log::error!(
target: "runtime",
target: "runtime::defensive",
"{}: {:?}: {:?}",
$crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
$error,
Expand Down