subspace_runtime_primitives/
utility.rs1use core::marker::PhantomData;
4use frame_support::pallet_prelude::TypeInfo;
5use frame_system::pallet_prelude::RuntimeCallFor;
6use scale_info::prelude::collections::VecDeque;
7use scale_info::prelude::vec;
8use sp_runtime::Vec;
9use sp_runtime::traits::{BlockNumberProvider, Get};
10
11pub trait MaybeUtilityCall<Runtime>
13where
14 Runtime: pallet_utility::Config,
15 for<'call> &'call RuntimeCallFor<Runtime>:
16 From<&'call <Runtime as pallet_utility::Config>::RuntimeCall>,
17{
18 fn maybe_utility_call(&self) -> Option<&pallet_utility::Call<Runtime>>;
20
21 fn maybe_nested_utility_calls(&self) -> Option<Vec<&RuntimeCallFor<Runtime>>> {
26 if let Some(call) = self.maybe_utility_call() {
27 match call {
28 pallet_utility::Call::batch { calls }
29 | pallet_utility::Call::batch_all { calls }
30 | pallet_utility::Call::force_batch { calls } => {
31 Some(calls.iter().map(Into::into).collect())
32 }
33 pallet_utility::Call::as_derivative { call, .. }
34 | pallet_utility::Call::dispatch_as { call, .. }
35 | pallet_utility::Call::dispatch_as_fallible { call, .. }
36 | pallet_utility::Call::with_weight { call, .. } => {
37 Some(vec![call.as_ref().into()])
38 }
39 pallet_utility::Call::if_else { main, fallback } => {
40 Some(vec![main.as_ref().into(), fallback.as_ref().into()])
41 }
42
43 pallet_utility::Call::__Ignore(..) => None,
44 }
45 } else {
46 None
47 }
48 }
49}
50
51pub trait MaybeMultisigCall<Runtime>
53where
54 Runtime: pallet_multisig::Config,
55 for<'call> &'call RuntimeCallFor<Runtime>:
56 From<&'call <Runtime as pallet_multisig::Config>::RuntimeCall>,
57{
58 fn maybe_multisig_call(&self) -> Option<&pallet_multisig::Call<Runtime>>;
60
61 fn maybe_nested_multisig_calls(&self) -> Option<Vec<&RuntimeCallFor<Runtime>>> {
66 if let Some(call) = self.maybe_multisig_call() {
67 match call {
68 pallet_multisig::Call::as_multi { call, .. }
69 | pallet_multisig::Call::as_multi_threshold_1 { call, .. } => Some(vec![call.as_ref().into()]),
70 pallet_multisig::Call::approve_as_multi { .. }
72 | pallet_multisig::Call::cancel_as_multi { .. }
73 | pallet_multisig::Call::__Ignore(..)
75 | pallet_multisig::Call::poke_deposit { .. }=> None,
76
77 }
78 } else {
79 None
80 }
81 }
82}
83
84pub trait MaybeNestedCall<Runtime: frame_system::Config> {
87 fn maybe_nested_call(&self) -> Option<Vec<&RuntimeCallFor<Runtime>>>;
92}
93
94pub fn nested_call_iter<Runtime>(
102 call: &RuntimeCallFor<Runtime>,
103) -> impl Iterator<Item = &RuntimeCallFor<Runtime>>
104where
105 Runtime: frame_system::Config,
106 RuntimeCallFor<Runtime>: MaybeNestedCall<Runtime>,
107{
108 let mut new_calls = VecDeque::from([call]);
110
111 core::iter::from_fn(move || {
112 let call = new_calls.pop_front()?;
113
114 for call in call.maybe_nested_call().into_iter().flatten() {
115 new_calls.push_front(call);
116 }
117
118 Some(call)
119 })
120}
121
122#[derive(Debug, TypeInfo)]
126pub struct DefaultNonceProvider<T, N>(PhantomData<(T, N)>);
127
128impl<N, T: BlockNumberProvider<BlockNumber = N>> Get<N> for DefaultNonceProvider<T, N> {
129 fn get() -> N {
130 T::current_block_number()
131 }
132}