#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::prelude::*;
use sp_runtime::traits::{StaticLookup, Dispatchable};
use frame_support::{
Parameter, decl_module, decl_event, decl_storage, decl_error, ensure,
};
use frame_support::weights::{GetDispatchInfo, FunctionOf};
use frame_system::{self as system, ensure_signed};
pub trait Trait: frame_system::Trait {
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
type Call: Parameter + Dispatchable<Origin=Self::Origin> + GetDispatchInfo;
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
type Error = Error<T>;
fn deposit_event() = default;
#[weight = FunctionOf(
|args: (&Box<<T as Trait>::Call>,)| args.0.get_dispatch_info().weight + 10_000,
|args: (&Box<<T as Trait>::Call>,)| args.0.get_dispatch_info().class,
true
)]
fn sudo(origin, call: Box<<T as Trait>::Call>) {
let sender = ensure_signed(origin)?;
ensure!(sender == Self::key(), Error::<T>::RequireSudo);
let res = match call.dispatch(frame_system::RawOrigin::Root.into()) {
Ok(_) => true,
Err(e) => {
sp_runtime::print(e);
false
}
};
Self::deposit_event(RawEvent::Sudid(res));
}
#[weight = frame_support::weights::SimpleDispatchInfo::default()]
fn set_key(origin, new: <T::Lookup as StaticLookup>::Source) {
let sender = ensure_signed(origin)?;
ensure!(sender == Self::key(), Error::<T>::RequireSudo);
let new = T::Lookup::lookup(new)?;
Self::deposit_event(RawEvent::KeyChanged(Self::key()));
<Key<T>>::put(new);
}
#[weight = FunctionOf(
|args: (&<T::Lookup as StaticLookup>::Source, &Box<<T as Trait>::Call>,)| {
args.1.get_dispatch_info().weight + 10_000
},
|args: (&<T::Lookup as StaticLookup>::Source, &Box<<T as Trait>::Call>,)| {
args.1.get_dispatch_info().class
},
true
)]
fn sudo_as(origin, who: <T::Lookup as StaticLookup>::Source, call: Box<<T as Trait>::Call>) {
let sender = ensure_signed(origin)?;
ensure!(sender == Self::key(), Error::<T>::RequireSudo);
let who = T::Lookup::lookup(who)?;
let res = match call.dispatch(frame_system::RawOrigin::Signed(who).into()) {
Ok(_) => true,
Err(e) => {
sp_runtime::print(e);
false
}
};
Self::deposit_event(RawEvent::SudoAsDone(res));
}
}
}
decl_event!(
pub enum Event<T> where AccountId = <T as frame_system::Trait>::AccountId {
Sudid(bool),
KeyChanged(AccountId),
SudoAsDone(bool),
}
);
decl_storage! {
trait Store for Module<T: Trait> as Sudo {
Key get(fn key) config(): T::AccountId;
}
}
decl_error! {
pub enum Error for Module<T: Trait> {
RequireSudo,
}
}