Crate pallet_sudo
source ·Expand description
Made with Substrate, for Polkadot.
§Sudo Pallet
A pallet to provide a way to execute privileged runtime calls using a specified sudo (“superuser do”) account.
§Pallet API
See the pallet
module for more information about the interfaces this pallet exposes,
including its configuration trait, dispatchables, storage items, events and errors.
§Overview
In Substrate blockchains, pallets may contain dispatchable calls that can only be called at
the system level of the chain (i.e. dispatchables that require a Root
origin).
Setting a privileged account, called the sudo key, allows you to make such calls as an
extrinsic.
Here’s an example of a privileged function in another pallet:
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
pub fn privileged_function(origin: OriginFor<T>) -> DispatchResult {
ensure_root(origin)?;
// do something...
Ok(())
}
}
}
With the Sudo pallet configured in your chain’s runtime you can execute this privileged
function by constructing a call using the sudo
dispatchable.
To use this pallet in your runtime, a sudo key must be specified in the GenesisConfig
of
the pallet. You can change this key at anytime once your chain is live using the
set_key
dispatchable, however only one sudo key can be set at a
time. The pallet also allows you to make a call using
sudo_unchecked_weight
, which allows the sudo account to
execute a call with a custom weight.
Note: this pallet is not meant to be used inside other pallets. It is only meant to be used by constructing runtime calls from outside the runtime.
This pallet also defines a TransactionExtension
called CheckOnlySudoAccount
to ensure that only signed transactions by the sudo account are
accepted by the transaction pool. The intended use of this signed extension is to prevent other
accounts from spamming the transaction pool for the initial phase of a chain, during which
developers may only want a sudo account to be able to make transactions.
Learn more about the Root
origin in the RawOrigin
type
documentation.
§Examples
- You can make a privileged runtime call using
sudo
with an account that matches the sudo key.
#[test]
fn sudo_basics() {
// Configure a default test environment and set the root `key` to 1.
new_test_ext(1).execute_with(|| {
// A privileged function should work when `sudo` is passed the root `key` as `origin`.
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
assert_eq!(Logger::i32_log(), vec![42i32]);
// A privileged function should not work when `sudo` is passed a non-root `key` as `origin`.
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_noop!(Sudo::sudo(RuntimeOrigin::signed(2), call), Error::<Test>::RequireSudo);
});
}
- Only an existing sudo key can set a new one.
#[test]
fn set_key_basics() {
new_test_ext(1).execute_with(|| {
// A root `key` can change the root `key`
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
assert_eq!(Key::<Test>::get(), Some(2u64));
});
new_test_ext(1).execute_with(|| {
// A non-root `key` will trigger a `RequireSudo` error and a non-root `key` cannot change
// the root `key`.
assert_noop!(Sudo::set_key(RuntimeOrigin::signed(2), 3), Error::<Test>::RequireSudo);
});
}
- You can also make non-privileged calls using
sudo_as
.
#[test]
fn sudo_as_emits_events_correctly() {
new_test_ext(1).execute_with(|| {
// A non-privileged function will work when passed to `sudo_as` with the root `key`.
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
System::assert_has_event(TestEvent::Sudo(Event::SudoAsDone { sudo_result: Ok(()) }));
});
}
§Low Level / Implementation Details
This pallet checks that the caller of its dispatchables is a signed account and ensures that the
caller matches the sudo key in storage.
A caller of this pallet’s dispatchables does not pay any fees to dispatch a call. If the account
making one of these calls is not the sudo key, the pallet returns a Error::RequireSudo
error.
Once an origin is verified, sudo calls use dispatch_bypass_filter
from the
UnfilteredDispatchable
trait to allow call
execution without enforcing any further origin checks.
Re-exports§
pub use weights::WeightInfo;
pub use pallet::*;
Modules§
- The
pallet
module in each FRAME pallet hosts the most important items needed to construct this pallet. - Autogenerated weights for
pallet_sudo
Structs§
- Ensure that signed transactions are only valid if they are signed by sudo account.