Crate pezpallet_sudo

Crate pezpallet_sudo 

Source
Expand description

Made with Bizinikiwi, for Pezkuwi.

github pezkuwi

§Sudo Pezpallet

A pezpallet to provide a way to execute privileged runtime calls using a specified sudo (“superuser do”) account.

§Pezpallet API

See the pezpallet module for more information about the interfaces this pezpallet exposes, including its configuration trait, dispatchables, storage items, events and errors.

§Overview

In Bizinikiwi 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 pezpallet:

#[pezframe_support::pezpallet]
pub mod pezpallet {
	use super::*;
	use pezframe_support::pezpallet_prelude::*;
	use pezframe_system::pezpallet_prelude::*;

	#[pezpallet::pezpallet]
	pub struct Pezpallet<T>(_);

	#[pezpallet::config]
	pub trait Config: pezframe_system::Config {}

	#[pezpallet::call]
	impl<T: Config> Pezpallet<T> {
		#[pezpallet::weight(0)]
        pub fn privileged_function(origin: OriginFor<T>) -> DispatchResult {
            ensure_root(origin)?;

            // do something...

            Ok(())
        }
	}
}

With the Sudo pezpallet configured in your chain’s runtime you can execute this privileged function by constructing a call using the sudo dispatchable.

To use this pezpallet in your runtime, a sudo key must be specified in the GenesisConfig of the pezpallet. 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 pezpallet 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 pezpallet 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 pezpallet 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

  1. 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);
	});
}
  1. 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);
	});
}
  1. 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 pezpallet 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 pezpallet’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 pezpallet 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 pezpallet::*;

Modules§

pezpallet
The pezpallet module in each FRAME pezpallet hosts the most important items needed to construct this pezpallet.
weights
Autogenerated weights for pezpallet_sudo

Structs§

CheckOnlySudoAccount
Ensure that signed transactions are only valid if they are signed by sudo account.