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::traits::{BlockNumberProvider, Get};
9use sp_runtime::Vec;
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::with_weight { call, .. } => {
36 Some(vec![call.as_ref().into()])
37 }
38 pallet_utility::Call::__Ignore(..) => None,
39 }
40 } else {
41 None
42 }
43 }
44}
45
46pub trait MaybeMultisigCall<Runtime>
48where
49 Runtime: pallet_multisig::Config,
50 for<'call> &'call RuntimeCallFor<Runtime>:
51 From<&'call <Runtime as pallet_multisig::Config>::RuntimeCall>,
52{
53 fn maybe_multisig_call(&self) -> Option<&pallet_multisig::Call<Runtime>>;
55
56 fn maybe_nested_multisig_calls(&self) -> Option<Vec<&RuntimeCallFor<Runtime>>> {
61 if let Some(call) = self.maybe_multisig_call() {
62 match call {
63 pallet_multisig::Call::as_multi { call, .. }
64 | pallet_multisig::Call::as_multi_threshold_1 { call, .. } => Some(vec![call.as_ref().into()]),
65 pallet_multisig::Call::approve_as_multi { .. }
67 | pallet_multisig::Call::cancel_as_multi { .. }
68 | pallet_multisig::Call::__Ignore(..) => None,
70 }
71 } else {
72 None
73 }
74 }
75}
76
77pub trait MaybeNestedCall<Runtime: frame_system::Config> {
80 fn maybe_nested_call(&self) -> Option<Vec<&RuntimeCallFor<Runtime>>>;
85}
86
87pub fn nested_call_iter<Runtime>(
95 call: &RuntimeCallFor<Runtime>,
96) -> impl Iterator<Item = &RuntimeCallFor<Runtime>>
97where
98 Runtime: frame_system::Config,
99 RuntimeCallFor<Runtime>: MaybeNestedCall<Runtime>,
100{
101 let mut new_calls = VecDeque::from([call]);
103
104 core::iter::from_fn(move || {
105 let call = new_calls.pop_front()?;
106
107 for call in call.maybe_nested_call().into_iter().flatten() {
108 new_calls.push_front(call);
109 }
110
111 Some(call)
112 })
113}
114
115#[derive(Debug, TypeInfo)]
119pub struct DefaultNonceProvider<T, N>(PhantomData<(T, N)>);
120
121impl<N, T: BlockNumberProvider<BlockNumber = N>> Get<N> for DefaultNonceProvider<T, N> {
122 fn get() -> N {
123 T::current_block_number()
124 }
125}