//! Custom origins for general governance interventions. use super::ranks; pub use pallet_cult_origins::*; #[frame_support::pallet] pub mod pallet_cult_origins { use crate::{Balance, CSPR}; use super::ranks; use frame_support::pallet_prelude::*; use pallet_ranked_collective::Rank; #[pallet::config] pub trait Config: frame_system::Config {} #[pallet::pallet] pub struct Pallet(_); #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] #[pallet::origin] pub enum Origin { Geniuses, Degens, Zombies, Skeletons, Ghosts, RetainAt1Level, RetainAt2Level, RetainAt3Level, RetainAt4Level, RetainAt5Level, PromoteTo1Level, PromoteTo2Level, PromoteTo3Level, PromoteTo4Level, PromoteTo5Level, } impl Origin { pub fn as_voice(&self) -> Option { Some(match &self { Origin::Geniuses => ranks::LEVEL_1, Origin::Degens => ranks::LEVEL_2, Origin::Zombies => ranks::LEVEL_3, Origin::Skeletons => ranks::LEVEL_4, Origin::Ghosts => ranks::LEVEL_5, _ => return None, }) } } pub struct ToVoice; impl<'a, O: 'a + TryInto<&'a Origin>> sp_runtime::traits::TryMorph for ToVoice { type Outcome = pallet_ranked_collective::Rank; fn try_morph(o: O) -> Result { o.try_into().ok().and_then(Origin::as_voice).ok_or(()) } } macro_rules! decl_unit_ensures { ( $name:ident: $success_type:ty = $success:expr ) => { pub struct $name; impl> + From> EnsureOrigin for $name { type Success = $success_type; fn try_origin(o: O) -> Result { o.into().and_then(|o| match o { Origin::$name => Ok($success), r => Err(O::from(r)), }) } #[cfg(feature = "runtime-benchmarks")] fn try_successful_origin() -> Result { Ok(O::from(Origin::$name)) } } }; ( $name:ident ) => { decl_unit_ensures! { $name : () = () } }; ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => { decl_unit_ensures! { $name: $success_type = $success } decl_unit_ensures! { $( $rest )* } }; ( $name:ident, $( $rest:tt )* ) => { decl_unit_ensures! { $name } decl_unit_ensures! { $( $rest )* } }; () => {} } decl_unit_ensures!( Geniuses: Rank = ranks::LEVEL_1, Degens: Rank = ranks::LEVEL_2, Zombies: Rank = ranks::LEVEL_3, Skeletons: Rank = ranks::LEVEL_4, Ghosts: Rank = ranks::LEVEL_5, ); macro_rules! decl_ensure { ( $vis:vis type $name:ident: EnsureOrigin { $( $item:ident = $success:expr, )* } ) => { $vis struct $name; impl> + From> EnsureOrigin for $name { type Success = $success_type; fn try_origin(o: O) -> Result { o.into().and_then(|o| match o { $( Origin::$item => Ok($success), )* r => Err(O::from(r)), }) } #[cfg(feature = "runtime-benchmarks")] fn try_successful_origin() -> Result { // By convention the more privileged origins go later, // so for greatest chance of success, we want the last one. let _result: Result = Err(()); $( let _result: Result = Ok(O::from(Origin::$item)); )* _result } } } } decl_ensure! { pub type EnsureCult: EnsureOrigin { Geniuses = ranks::LEVEL_1, Degens = ranks::LEVEL_2, Zombies = ranks::LEVEL_3, Skeletons = ranks::LEVEL_4, Ghosts = ranks::LEVEL_5, } } decl_ensure! { pub type EnsureCanRetainAt: EnsureOrigin { RetainAt1Level = ranks::LEVEL_1, RetainAt2Level = ranks::LEVEL_2, RetainAt3Level = ranks::LEVEL_3, RetainAt4Level = ranks::LEVEL_4, RetainAt5Level = ranks::LEVEL_5, } } decl_ensure! { pub type EnsureCanPromoteTo: EnsureOrigin { PromoteTo1Level = ranks::LEVEL_1, PromoteTo2Level = ranks::LEVEL_2, PromoteTo3Level = ranks::LEVEL_3, PromoteTo4Level = ranks::LEVEL_4, PromoteTo5Level = ranks::LEVEL_5, } } decl_ensure! { pub type CultTreasurySpender: EnsureOrigin { Geniuses = 50 * CSPR, Degens = 100 * CSPR, Zombies = 500 * CSPR, Skeletons = 1_000 * CSPR, Ghosts = 10_000 * CSPR, } } }