subspace_runtime/
signed_extensions.rs
1use crate::{Runtime, RuntimeCall, RuntimeConfigs};
2use frame_support::pallet_prelude::Weight;
3use frame_system::pallet_prelude::{OriginFor, RuntimeCallFor};
4use parity_scale_codec::{Decode, Encode};
5use scale_info::TypeInfo;
6use sp_runtime::impl_tx_ext_default;
7use sp_runtime::traits::{
8 AsSystemOriginSigner, DispatchInfoOf, TransactionExtension, ValidateResult,
9};
10use sp_runtime::transaction_validity::{
11 InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
12 ValidTransaction,
13};
14use sp_std::prelude::*;
15use subspace_runtime_primitives::utility::nested_call_iter;
16
17#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, Default, TypeInfo)]
19pub struct DisablePallets;
20
21impl DisablePallets {
22 fn do_validate_unsigned(call: &RuntimeCall) -> TransactionValidity {
23 if matches!(call, RuntimeCall::Domains(_)) && !RuntimeConfigs::enable_domains() {
24 InvalidTransaction::Call.into()
25 } else {
26 Ok(ValidTransaction::default())
27 }
28 }
29
30 fn do_validate_signed(call: &RuntimeCall) -> TransactionValidity {
31 if !RuntimeConfigs::enable_balance_transfers() && contains_balance_transfer(call) {
33 Err(InvalidTransaction::Call.into())
34 } else {
35 Ok(ValidTransaction::default())
36 }
37 }
38}
39
40impl TransactionExtension<RuntimeCall> for DisablePallets {
41 const IDENTIFIER: &'static str = "DisablePallets";
42 type Implicit = ();
43 type Val = ();
44 type Pre = ();
45
46 fn weight(&self, _call: &RuntimeCall) -> Weight {
48 <Runtime as frame_system::Config>::DbWeight::get().reads(1)
50 }
51
52 fn validate(
53 &self,
54 origin: OriginFor<Runtime>,
55 call: &RuntimeCallFor<Runtime>,
56 _info: &DispatchInfoOf<RuntimeCallFor<Runtime>>,
57 _len: usize,
58 _self_implicit: Self::Implicit,
59 _inherited_implication: &impl Encode,
60 _source: TransactionSource,
61 ) -> ValidateResult<Self::Val, RuntimeCallFor<Runtime>> {
62 let validity = if origin.as_system_origin_signer().is_some() {
63 Self::do_validate_signed(call)?
64 } else {
65 ValidTransaction::default()
66 };
67
68 Ok((validity, (), origin))
69 }
70
71 impl_tx_ext_default!(RuntimeCallFor<Runtime>; prepare);
72
73 fn bare_validate(
74 call: &RuntimeCallFor<Runtime>,
75 _info: &DispatchInfoOf<RuntimeCallFor<Runtime>>,
76 _len: usize,
77 ) -> TransactionValidity {
78 Self::do_validate_unsigned(call)
79 }
80
81 fn bare_validate_and_prepare(
82 call: &RuntimeCallFor<Runtime>,
83 _info: &DispatchInfoOf<RuntimeCallFor<Runtime>>,
84 _len: usize,
85 ) -> Result<(), TransactionValidityError> {
86 Self::do_validate_unsigned(call)?;
87 Ok(())
88 }
89}
90
91fn contains_balance_transfer(call: &RuntimeCall) -> bool {
92 for call in nested_call_iter::<Runtime>(call) {
93 if let RuntimeCall::Balances(
96 pallet_balances::Call::transfer_allow_death { .. }
97 | pallet_balances::Call::transfer_keep_alive { .. }
98 | pallet_balances::Call::transfer_all { .. },
99 ) = call
100 {
101 return true;
102 }
103 }
104
105 false
106}