From e079cdc40454f5847e20e1c62b1ee98f968ee704 Mon Sep 17 00:00:00 2001 From: Gonza Montiel Date: Thu, 30 Oct 2025 09:38:18 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=A9=B9=20add=20mandatory=20extrins?= =?UTF-8?q?ics=20to=20safe=20mode=20whitelisted=20calls=20(#265)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Fix: Safe Mode Whitelisted Calls - enable block production ## Problem The safe mode whitelist was missing critical runtime calls needed for block production, generating this error: ``` 2025-10-29 17:29:48 Proposing failed: Import failed: Extrinsic is not valid: TransactionValidityError::Invalid(InvalidTransaction::BadMandatory) ``` The SafeMode filter needs to include all RuntimeCalls that have inherents marked as `DispatchClass::Mandatory`, as you can see [here](https://github.com/paritytech/polkadot-sdk/blob/bbc435c7667d3283ba280a8fec44676357392753/substrate/frame/executive/src/lib.rs#L806). If a single inherent is missing the whole block will not be valid, causing the chain to stall. ## Solution Bisect all the calls to find the culprit, until find it was the pallet Randomness. I included it in `SafeModeWhitelistedCalls` and blocks are being produced in SafeMode. --- operator/runtime/mainnet/src/configs/mod.rs | 4 +++- operator/runtime/stagenet/src/configs/mod.rs | 4 +++- operator/runtime/testnet/src/configs/mod.rs | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/operator/runtime/mainnet/src/configs/mod.rs b/operator/runtime/mainnet/src/configs/mod.rs index 0b8b8a06..3f828e33 100644 --- a/operator/runtime/mainnet/src/configs/mod.rs +++ b/operator/runtime/mainnet/src/configs/mod.rs @@ -236,7 +236,7 @@ impl Contains for NormalCallFilter { } /// Calls that can bypass the safe-mode pallet. -/// These calls are essential for emergency governance and system maintenance. +/// These calls are essential for emergency governance, system maintenance, and basic operation. pub struct SafeModeWhitelistedCalls; impl Contains for SafeModeWhitelistedCalls { fn contains(call: &RuntimeCall) -> bool { @@ -257,6 +257,8 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, + // Block production - needed to continue producing blocks in safe mode + RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/operator/runtime/stagenet/src/configs/mod.rs b/operator/runtime/stagenet/src/configs/mod.rs index f9b31e70..9ab30486 100644 --- a/operator/runtime/stagenet/src/configs/mod.rs +++ b/operator/runtime/stagenet/src/configs/mod.rs @@ -236,7 +236,7 @@ impl Contains for NormalCallFilter { } /// Calls that can bypass the safe-mode pallet. -/// These calls are essential for emergency governance and system maintenance. +/// These calls are essential for emergency governance, system maintenance, and basic operation. pub struct SafeModeWhitelistedCalls; impl Contains for SafeModeWhitelistedCalls { fn contains(call: &RuntimeCall) -> bool { @@ -257,6 +257,8 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, + // Block production - needed to continue producing blocks in safe mode + RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/operator/runtime/testnet/src/configs/mod.rs b/operator/runtime/testnet/src/configs/mod.rs index 7a9dc4b6..5915e31f 100644 --- a/operator/runtime/testnet/src/configs/mod.rs +++ b/operator/runtime/testnet/src/configs/mod.rs @@ -236,7 +236,7 @@ impl Contains for NormalCallFilter { } /// Calls that can bypass the safe-mode pallet. -/// These calls are essential for emergency governance and system maintenance. +/// These calls are essential for emergency governance, system maintenance, and basic operation. pub struct SafeModeWhitelistedCalls; impl Contains for SafeModeWhitelistedCalls { fn contains(call: &RuntimeCall) -> bool { @@ -257,6 +257,8 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, + // Block production - needed to continue producing blocks in safe mode + RuntimeCall::Randomness(_) => true, _ => false, } }