1use crate::dispatch::{DispatchResult, Parameter};
21use alloc::{vec, vec::Vec};
22use codec::{CompactLen, Decode, DecodeLimit, Encode, EncodeLike, Input, MaxEncodedLen};
23use impl_trait_for_tuples::impl_for_tuples;
24use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter};
25use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, One, Saturating};
26use sp_core::bounded::bounded_vec::TruncateFrom;
27
28use core::cmp::Ordering;
29#[doc(hidden)]
30pub use sp_runtime::traits::{
31 ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, ConstU32,
32 ConstU64, ConstU8, Get, GetDefault, TryCollect, TypedGet,
33};
34use sp_runtime::{traits::Block as BlockT, DispatchError};
35
36#[doc(hidden)]
37pub const DEFENSIVE_OP_PUBLIC_ERROR: &str = "a defensive failure has been triggered; please report the block number at https://github.com/paritytech/substrate/issues";
38#[doc(hidden)]
39pub const DEFENSIVE_OP_INTERNAL_ERROR: &str = "Defensive failure has been triggered!";
40
41pub trait VariantCount {
43 const VARIANT_COUNT: u32;
45}
46
47impl VariantCount for () {
48 const VARIANT_COUNT: u32 = 0;
49}
50
51impl VariantCount for u8 {
52 const VARIANT_COUNT: u32 = 256;
53}
54
55pub struct VariantCountOf<T: VariantCount>(core::marker::PhantomData<T>);
57impl<T: VariantCount> Get<u32> for VariantCountOf<T> {
58 fn get() -> u32 {
59 T::VARIANT_COUNT
60 }
61}
62
63#[macro_export]
67macro_rules! defensive {
68 () => {
69 frame_support::__private::log::error!(
70 target: "runtime::defensive",
71 "{}",
72 $crate::traits::DEFENSIVE_OP_PUBLIC_ERROR
73 );
74 debug_assert!(false, "{}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR);
75 };
76 ($error:expr $(,)?) => {
77 frame_support::__private::log::error!(
78 target: "runtime::defensive",
79 "{}: {:?}",
80 $crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
81 $error
82 );
83 debug_assert!(false, "{}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error);
84 };
85 ($error:expr, $proof:expr $(,)?) => {
86 frame_support::__private::log::error!(
87 target: "runtime::defensive",
88 "{}: {:?}: {:?}",
89 $crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
90 $error,
91 $proof,
92 );
93 debug_assert!(false, "{}: {:?}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error, $proof);
94 }
95}
96
97#[macro_export]
108macro_rules! defensive_assert {
109 ($cond:expr $(, $proof:expr )? $(,)?) => {
110 if !($cond) {
111 $crate::defensive!(::core::stringify!($cond) $(, $proof )?);
112 }
113 };
114}
115
116pub mod defensive_prelude {
118 pub use super::{Defensive, DefensiveOption, DefensiveResult};
119}
120
121pub trait Defensive<T> {
139 fn defensive_unwrap_or(self, other: T) -> T;
142
143 fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T;
146
147 fn defensive_unwrap_or_default(self) -> T
150 where
151 T: Default;
152
153 fn defensive(self) -> Self;
165
166 fn defensive_proof(self, proof: &'static str) -> Self;
169}
170
171pub trait DefensiveResult<T, E> {
173 fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F>;
176
177 fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;
180
181 fn defensive_ok(self) -> Option<T>;
184
185 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E>;
188}
189
190pub trait DefensiveOption<T> {
192 fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;
195
196 fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E>;
199
200 fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E>;
202
203 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U>;
206}
207
208impl<T> Defensive<T> for Option<T> {
209 fn defensive_unwrap_or(self, or: T) -> T {
210 match self {
211 Some(inner) => inner,
212 None => {
213 defensive!();
214 or
215 },
216 }
217 }
218
219 fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
220 match self {
221 Some(inner) => inner,
222 None => {
223 defensive!();
224 f()
225 },
226 }
227 }
228
229 fn defensive_unwrap_or_default(self) -> T
230 where
231 T: Default,
232 {
233 match self {
234 Some(inner) => inner,
235 None => {
236 defensive!();
237 Default::default()
238 },
239 }
240 }
241
242 fn defensive(self) -> Self {
243 match self {
244 Some(inner) => Some(inner),
245 None => {
246 defensive!();
247 None
248 },
249 }
250 }
251
252 fn defensive_proof(self, proof: &'static str) -> Self {
253 if self.is_none() {
254 defensive!(proof);
255 }
256 self
257 }
258}
259
260impl<T, E: core::fmt::Debug> Defensive<T> for Result<T, E> {
261 fn defensive_unwrap_or(self, or: T) -> T {
262 match self {
263 Ok(inner) => inner,
264 Err(e) => {
265 defensive!(e);
266 or
267 },
268 }
269 }
270
271 fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
272 match self {
273 Ok(inner) => inner,
274 Err(e) => {
275 defensive!(e);
276 f()
277 },
278 }
279 }
280
281 fn defensive_unwrap_or_default(self) -> T
282 where
283 T: Default,
284 {
285 match self {
286 Ok(inner) => inner,
287 Err(e) => {
288 defensive!(e);
289 Default::default()
290 },
291 }
292 }
293
294 fn defensive(self) -> Self {
295 match self {
296 Ok(inner) => Ok(inner),
297 Err(e) => {
298 defensive!(e);
299 Err(e)
300 },
301 }
302 }
303
304 fn defensive_proof(self, proof: &'static str) -> Self {
305 match self {
306 Ok(inner) => Ok(inner),
307 Err(e) => {
308 defensive!(e, proof);
309 Err(e)
310 },
311 }
312 }
313}
314
315impl<T, E: core::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
316 fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F> {
317 self.map_err(|e| {
318 defensive!(e);
319 o(e)
320 })
321 }
322
323 fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
324 self.map_or_else(
325 |e| {
326 defensive!(e);
327 default(e)
328 },
329 f,
330 )
331 }
332
333 fn defensive_ok(self) -> Option<T> {
334 match self {
335 Ok(inner) => Some(inner),
336 Err(e) => {
337 defensive!(e);
338 None
339 },
340 }
341 }
342
343 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E> {
344 match self {
345 Ok(inner) => Ok(f(inner)),
346 Err(e) => {
347 defensive!(e);
348 Err(e)
349 },
350 }
351 }
352}
353
354impl<T> DefensiveOption<T> for Option<T> {
355 fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
356 self.map_or_else(
357 || {
358 defensive!();
359 default()
360 },
361 f,
362 )
363 }
364
365 fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
366 self.ok_or_else(|| {
367 let err_value = err();
368 defensive!(err_value);
369 err_value
370 })
371 }
372
373 fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E> {
374 self.ok_or_else(|| {
375 defensive!(err);
376 err
377 })
378 }
379
380 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
381 match self {
382 Some(inner) => Some(f(inner)),
383 None => {
384 defensive!();
385 None
386 },
387 }
388 }
389}
390
391pub trait DefensiveSaturating {
394 fn defensive_saturating_add(self, other: Self) -> Self;
396 fn defensive_saturating_sub(self, other: Self) -> Self;
398 fn defensive_saturating_mul(self, other: Self) -> Self;
400 fn defensive_saturating_accrue(&mut self, other: Self);
402 fn defensive_saturating_reduce(&mut self, other: Self);
404 fn defensive_saturating_inc(&mut self);
406 fn defensive_saturating_dec(&mut self);
408}
409
410impl<T: Saturating + CheckedAdd + CheckedMul + CheckedSub + One> DefensiveSaturating for T {
413 fn defensive_saturating_add(self, other: Self) -> Self {
414 self.checked_add(&other).defensive_unwrap_or_else(|| self.saturating_add(other))
415 }
416 fn defensive_saturating_sub(self, other: Self) -> Self {
417 self.checked_sub(&other).defensive_unwrap_or_else(|| self.saturating_sub(other))
418 }
419 fn defensive_saturating_mul(self, other: Self) -> Self {
420 self.checked_mul(&other).defensive_unwrap_or_else(|| self.saturating_mul(other))
421 }
422 fn defensive_saturating_accrue(&mut self, other: Self) {
423 *self = core::mem::replace(self, One::one()).defensive_saturating_add(other);
425 }
426 fn defensive_saturating_reduce(&mut self, other: Self) {
427 *self = core::mem::replace(self, One::one()).defensive_saturating_sub(other);
429 }
430 fn defensive_saturating_inc(&mut self) {
431 self.defensive_saturating_accrue(One::one());
432 }
433 fn defensive_saturating_dec(&mut self) {
434 self.defensive_saturating_reduce(One::one());
435 }
436}
437
438pub trait DefensiveTruncateFrom<T> {
440 fn defensive_truncate_from(unbound: T) -> Self;
454}
455
456impl<T, U> DefensiveTruncateFrom<U> for T
457where
458 T: TruncateFrom<U> + TryFrom<U, Error = U>,
463{
464 fn defensive_truncate_from(unbound: U) -> Self {
465 unbound.try_into().map_or_else(
466 |err| {
467 defensive!("DefensiveTruncateFrom truncating");
468 T::truncate_from(err)
469 },
470 |bound| bound,
471 )
472 }
473}
474
475pub trait DefensiveMin<T> {
479 fn defensive_min(self, other: T) -> Self;
497
498 fn defensive_strict_min(self, other: T) -> Self;
514}
515
516impl<T> DefensiveMin<T> for T
517where
518 T: PartialOrd<T>,
519{
520 fn defensive_min(self, other: T) -> Self {
521 if self <= other {
522 self
523 } else {
524 defensive!("DefensiveMin");
525 other
526 }
527 }
528
529 fn defensive_strict_min(self, other: T) -> Self {
530 if self < other {
531 self
532 } else {
533 defensive!("DefensiveMin strict");
534 other
535 }
536 }
537}
538
539pub trait DefensiveMax<T> {
543 fn defensive_max(self, other: T) -> Self;
561
562 fn defensive_strict_max(self, other: T) -> Self;
578}
579
580impl<T> DefensiveMax<T> for T
581where
582 T: PartialOrd<T>,
583{
584 fn defensive_max(self, other: T) -> Self {
585 if self >= other {
586 self
587 } else {
588 defensive!("DefensiveMax");
589 other
590 }
591 }
592
593 fn defensive_strict_max(self, other: T) -> Self {
594 if self > other {
595 self
596 } else {
597 defensive!("DefensiveMax strict");
598 other
599 }
600 }
601}
602
603pub trait Len {
605 fn len(&self) -> usize;
607}
608
609impl<T: IntoIterator + Clone> Len for T
610where
611 <T as IntoIterator>::IntoIter: ExactSizeIterator,
612{
613 fn len(&self) -> usize {
614 self.clone().into_iter().len()
615 }
616}
617
618pub trait TryDrop: Sized {
620 fn try_drop(self) -> Result<(), Self>;
622}
623
624impl TryDrop for () {
625 fn try_drop(self) -> Result<(), Self> {
626 Ok(())
627 }
628}
629
630pub enum SameOrOther<A, B> {
634 None,
636 Same(A),
638 Other(B),
640}
641
642impl<A, B> TryDrop for SameOrOther<A, B> {
643 fn try_drop(self) -> Result<(), Self> {
644 if let SameOrOther::None = self {
645 Ok(())
646 } else {
647 Err(self)
648 }
649 }
650}
651
652impl<A, B> SameOrOther<A, B> {
653 pub fn try_same(self) -> Result<A, Self> {
656 match self {
657 SameOrOther::Same(a) => Ok(a),
658 x => Err(x),
659 }
660 }
661
662 pub fn try_other(self) -> Result<B, Self> {
665 match self {
666 SameOrOther::Other(b) => Ok(b),
667 x => Err(x),
668 }
669 }
670
671 pub fn try_none(self) -> Result<(), Self> {
673 match self {
674 SameOrOther::None => Ok(()),
675 x => Err(x),
676 }
677 }
678
679 pub fn same(self) -> Result<A, B>
680 where
681 A: Default,
682 {
683 match self {
684 SameOrOther::Same(a) => Ok(a),
685 SameOrOther::None => Ok(A::default()),
686 SameOrOther::Other(b) => Err(b),
687 }
688 }
689
690 pub fn other(self) -> Result<B, A>
691 where
692 B: Default,
693 {
694 match self {
695 SameOrOther::Same(a) => Err(a),
696 SameOrOther::None => Ok(B::default()),
697 SameOrOther::Other(b) => Ok(b),
698 }
699 }
700}
701
702#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
704#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
705#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
706pub trait OnNewAccount<AccountId> {
707 fn on_new_account(who: &AccountId);
709}
710
711#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
713#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
714#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
715pub trait OnKilledAccount<AccountId> {
716 fn on_killed_account(who: &AccountId);
718}
719
720pub trait HandleLifetime<T> {
722 fn created(_t: &T) -> Result<(), DispatchError> {
724 Ok(())
725 }
726
727 fn killed(_t: &T) -> Result<(), DispatchError> {
729 Ok(())
730 }
731}
732
733impl<T> HandleLifetime<T> for () {}
734
735pub trait Time {
736 type Moment: sp_arithmetic::traits::AtLeast32Bit + Parameter + Default + Copy + MaxEncodedLen;
737
738 fn now() -> Self::Moment;
739}
740
741pub trait UnixTime {
743 fn now() -> core::time::Duration;
745}
746
747pub trait IsType<T>: Into<T> + From<T> {
751 fn from_ref(t: &T) -> &Self;
753
754 fn into_ref(&self) -> &T;
756
757 fn from_mut(t: &mut T) -> &mut Self;
759
760 fn into_mut(&mut self) -> &mut T;
762}
763
764impl<T> IsType<T> for T {
765 fn from_ref(t: &T) -> &Self {
766 t
767 }
768 fn into_ref(&self) -> &T {
769 self
770 }
771 fn from_mut(t: &mut T) -> &mut Self {
772 t
773 }
774 fn into_mut(&mut self) -> &mut T {
775 self
776 }
777}
778
779pub trait IsSubType<T> {
822 fn is_sub_type(&self) -> Option<&T>;
824}
825
826pub trait ExecuteBlock<Block: BlockT> {
831 fn execute_block(block: Block);
840}
841
842pub trait PrivilegeCmp<Origin> {
844 fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering>;
850}
851
852pub struct EqualPrivilegeOnly;
856impl<Origin: PartialEq> PrivilegeCmp<Origin> for EqualPrivilegeOnly {
857 fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering> {
858 (left == right).then(|| Ordering::Equal)
859 }
860}
861
862#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
873#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
874#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
875pub trait OffchainWorker<BlockNumber> {
876 fn offchain_worker(_n: BlockNumber) {}
883}
884
885pub struct Backing {
888 pub approvals: u32,
890 pub eligible: u32,
892}
893
894pub trait GetBacking {
896 fn get_backing(&self) -> Option<Backing>;
899}
900
901pub trait EnsureInherentsAreFirst<Block: sp_runtime::traits::Block>:
905 IsInherent<<Block as sp_runtime::traits::Block>::Extrinsic>
906{
907 fn ensure_inherents_are_first(block: &Block) -> Result<u32, u32>;
913}
914
915pub trait IsInherent<Extrinsic> {
917 fn is_inherent(ext: &Extrinsic) -> bool;
919}
920
921pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic {
923 fn call(&self) -> &Self::Call;
925}
926
927#[cfg(feature = "std")]
928impl<Call, Extra> ExtrinsicCall for sp_runtime::testing::TestXt<Call, Extra>
929where
930 Call: codec::Codec + Sync + Send + TypeInfo,
931 Extra: TypeInfo,
932{
933 fn call(&self) -> &Self::Call {
934 &self.call
935 }
936}
937
938impl<Address, Call, Signature, Extra> ExtrinsicCall
939 for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
940where
941 Address: TypeInfo,
942 Call: TypeInfo,
943 Signature: TypeInfo,
944 Extra: sp_runtime::traits::SignedExtension + TypeInfo,
945{
946 fn call(&self) -> &Self::Call {
947 &self.function
948 }
949}
950
951pub trait EstimateCallFee<Call, Balance> {
955 fn estimate_call_fee(call: &Call, post_info: crate::dispatch::PostDispatchInfo) -> Balance;
960}
961
962#[cfg(feature = "std")]
964impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
965 fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
966 T.into()
967 }
968}
969
970#[derive(Debug, Eq, PartialEq, Default, Clone)]
975#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
976pub struct WrapperOpaque<T>(pub T);
977
978impl<T: Encode> EncodeLike for WrapperOpaque<T> {}
979impl<T: Encode> EncodeLike<WrapperKeepOpaque<T>> for WrapperOpaque<T> {}
980
981impl<T: Encode> Encode for WrapperOpaque<T> {
982 fn size_hint(&self) -> usize {
983 self.0.size_hint().saturating_add(<codec::Compact<u32>>::max_encoded_len())
984 }
985
986 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
987 self.0.encode().encode_to(dest);
988 }
989
990 fn encode(&self) -> Vec<u8> {
991 self.0.encode().encode()
992 }
993
994 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
995 self.0.encode().using_encoded(f)
996 }
997}
998
999impl<T: Decode> Decode for WrapperOpaque<T> {
1000 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1001 Ok(Self(T::decode_all_with_depth_limit(
1002 sp_api::MAX_EXTRINSIC_DEPTH,
1003 &mut &<Vec<u8>>::decode(input)?[..],
1004 )?))
1005 }
1006
1007 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1008 <Vec<u8>>::skip(input)
1009 }
1010}
1011
1012impl<T> From<T> for WrapperOpaque<T> {
1013 fn from(t: T) -> Self {
1014 Self(t)
1015 }
1016}
1017
1018impl<T: MaxEncodedLen> MaxEncodedLen for WrapperOpaque<T> {
1019 fn max_encoded_len() -> usize {
1020 let t_max_len = T::max_encoded_len();
1021
1022 if t_max_len < 64 {
1024 t_max_len + 1
1025 } else if t_max_len < 2usize.pow(14) {
1026 t_max_len + 2
1027 } else if t_max_len < 2usize.pow(30) {
1028 t_max_len + 4
1029 } else {
1030 <codec::Compact<u32>>::max_encoded_len().saturating_add(T::max_encoded_len())
1031 }
1032 }
1033}
1034
1035impl<T: TypeInfo + 'static> TypeInfo for WrapperOpaque<T> {
1036 type Identity = Self;
1037 fn type_info() -> Type {
1038 Type::builder()
1039 .path(Path::new("WrapperOpaque", module_path!()))
1040 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1041 .composite(
1042 Fields::unnamed()
1043 .field(|f| f.compact::<u32>())
1044 .field(|f| f.ty::<T>().type_name("T")),
1045 )
1046 }
1047}
1048
1049#[derive(Debug, Eq, PartialEq, Default, Clone)]
1056pub struct WrapperKeepOpaque<T> {
1057 data: Vec<u8>,
1058 _phantom: core::marker::PhantomData<T>,
1059}
1060
1061impl<T: Decode> WrapperKeepOpaque<T> {
1062 pub fn try_decode(&self) -> Option<T> {
1066 T::decode_all_with_depth_limit(sp_api::MAX_EXTRINSIC_DEPTH, &mut &self.data[..]).ok()
1067 }
1068
1069 pub fn encoded_len(&self) -> usize {
1071 self.data.len()
1072 }
1073
1074 pub fn encoded(&self) -> &[u8] {
1076 &self.data
1077 }
1078
1079 pub fn from_encoded(data: Vec<u8>) -> Self {
1081 Self { data, _phantom: core::marker::PhantomData }
1082 }
1083}
1084
1085impl<T: Encode> EncodeLike for WrapperKeepOpaque<T> {}
1086impl<T: Encode> EncodeLike<WrapperOpaque<T>> for WrapperKeepOpaque<T> {}
1087
1088impl<T: Encode> Encode for WrapperKeepOpaque<T> {
1089 fn size_hint(&self) -> usize {
1090 self.data.len() + codec::Compact::<u32>::compact_len(&(self.data.len() as u32))
1091 }
1092
1093 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1094 self.data.encode_to(dest);
1095 }
1096
1097 fn encode(&self) -> Vec<u8> {
1098 self.data.encode()
1099 }
1100
1101 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1102 self.data.using_encoded(f)
1103 }
1104}
1105
1106impl<T: Decode> Decode for WrapperKeepOpaque<T> {
1107 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1108 Ok(Self { data: Vec::<u8>::decode(input)?, _phantom: core::marker::PhantomData })
1109 }
1110
1111 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1112 <Vec<u8>>::skip(input)
1113 }
1114}
1115
1116impl<T: MaxEncodedLen> MaxEncodedLen for WrapperKeepOpaque<T> {
1117 fn max_encoded_len() -> usize {
1118 WrapperOpaque::<T>::max_encoded_len()
1119 }
1120}
1121
1122impl<T: TypeInfo + 'static> TypeInfo for WrapperKeepOpaque<T> {
1123 type Identity = Self;
1124 fn type_info() -> Type {
1125 Type::builder()
1126 .path(Path::new("WrapperKeepOpaque", module_path!()))
1127 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1128 .composite(
1129 Fields::unnamed()
1130 .field(|f| f.compact::<u32>())
1131 .field(|f| f.ty::<T>().type_name("T")),
1132 )
1133 }
1134}
1135
1136pub trait PreimageProvider<Hash> {
1138 fn have_preimage(hash: &Hash) -> bool;
1142
1143 fn get_preimage(hash: &Hash) -> Option<Vec<u8>>;
1145
1146 fn preimage_requested(hash: &Hash) -> bool;
1148
1149 fn request_preimage(hash: &Hash);
1152
1153 fn unrequest_preimage(hash: &Hash);
1155}
1156
1157impl<Hash> PreimageProvider<Hash> for () {
1158 fn have_preimage(_: &Hash) -> bool {
1159 false
1160 }
1161 fn get_preimage(_: &Hash) -> Option<Vec<u8>> {
1162 None
1163 }
1164 fn preimage_requested(_: &Hash) -> bool {
1165 false
1166 }
1167 fn request_preimage(_: &Hash) {}
1168 fn unrequest_preimage(_: &Hash) {}
1169}
1170
1171pub trait PreimageRecipient<Hash>: PreimageProvider<Hash> {
1177 type MaxSize: Get<u32>;
1179
1180 fn note_preimage(bytes: crate::BoundedVec<u8, Self::MaxSize>);
1182
1183 fn unnote_preimage(hash: &Hash);
1187}
1188
1189impl<Hash> PreimageRecipient<Hash> for () {
1190 type MaxSize = ();
1191 fn note_preimage(_: crate::BoundedVec<u8, Self::MaxSize>) {}
1192 fn unnote_preimage(_: &Hash) {}
1193}
1194
1195pub trait AccountTouch<AssetId, AccountId> {
1204 type Balance;
1206
1207 fn deposit_required(asset: AssetId) -> Self::Balance;
1209
1210 fn should_touch(asset: AssetId, who: &AccountId) -> bool;
1212
1213 fn touch(asset: AssetId, who: &AccountId, depositor: &AccountId) -> DispatchResult;
1215}
1216
1217#[cfg(test)]
1218mod test {
1219 use super::*;
1220 use core::marker::PhantomData;
1221 use sp_core::bounded::{BoundedSlice, BoundedVec};
1222
1223 #[test]
1224 fn defensive_assert_works() {
1225 defensive_assert!(true);
1226 defensive_assert!(true,);
1227 defensive_assert!(true, "must work");
1228 defensive_assert!(true, "must work",);
1229 }
1230
1231 #[test]
1232 #[cfg(debug_assertions)]
1233 #[should_panic(expected = "Defensive failure has been triggered!: \"1 == 0\": \"Must fail\"")]
1234 fn defensive_assert_panics() {
1235 defensive_assert!(1 == 0, "Must fail");
1236 }
1237
1238 #[test]
1239 #[cfg(not(debug_assertions))]
1240 fn defensive_assert_does_not_panic() {
1241 defensive_assert!(1 == 0, "Must fail");
1242 }
1243
1244 #[test]
1245 #[cfg(not(debug_assertions))]
1246 fn defensive_saturating_accrue_works() {
1247 let mut v = 1_u32;
1248 v.defensive_saturating_accrue(2);
1249 assert_eq!(v, 3);
1250 v.defensive_saturating_accrue(u32::MAX);
1251 assert_eq!(v, u32::MAX);
1252 v.defensive_saturating_accrue(1);
1253 assert_eq!(v, u32::MAX);
1254 }
1255
1256 #[test]
1257 #[cfg(debug_assertions)]
1258 #[should_panic(expected = "Defensive")]
1259 fn defensive_saturating_accrue_panics() {
1260 let mut v = u32::MAX;
1261 v.defensive_saturating_accrue(1); }
1263
1264 #[test]
1265 #[cfg(not(debug_assertions))]
1266 fn defensive_saturating_reduce_works() {
1267 let mut v = u32::MAX;
1268 v.defensive_saturating_reduce(3);
1269 assert_eq!(v, u32::MAX - 3);
1270 v.defensive_saturating_reduce(u32::MAX);
1271 assert_eq!(v, 0);
1272 v.defensive_saturating_reduce(1);
1273 assert_eq!(v, 0);
1274 }
1275
1276 #[test]
1277 #[cfg(debug_assertions)]
1278 #[should_panic(expected = "Defensive")]
1279 fn defensive_saturating_reduce_panics() {
1280 let mut v = 0_u32;
1281 v.defensive_saturating_reduce(1); }
1283
1284 #[test]
1285 #[cfg(not(debug_assertions))]
1286 fn defensive_saturating_inc_works() {
1287 let mut v = 0_u32;
1288 for i in 1..10 {
1289 v.defensive_saturating_inc();
1290 assert_eq!(v, i);
1291 }
1292 v += u32::MAX - 10;
1293 v.defensive_saturating_inc();
1294 assert_eq!(v, u32::MAX);
1295 v.defensive_saturating_inc();
1296 assert_eq!(v, u32::MAX);
1297 }
1298
1299 #[test]
1300 #[cfg(debug_assertions)]
1301 #[should_panic(expected = "Defensive")]
1302 fn defensive_saturating_inc_panics() {
1303 let mut v = u32::MAX;
1304 v.defensive_saturating_inc(); }
1306
1307 #[test]
1308 #[cfg(not(debug_assertions))]
1309 fn defensive_saturating_dec_works() {
1310 let mut v = u32::MAX;
1311 for i in 1..10 {
1312 v.defensive_saturating_dec();
1313 assert_eq!(v, u32::MAX - i);
1314 }
1315 v -= u32::MAX - 10;
1316 v.defensive_saturating_dec();
1317 assert_eq!(v, 0);
1318 v.defensive_saturating_dec();
1319 assert_eq!(v, 0);
1320 }
1321
1322 #[test]
1323 #[cfg(debug_assertions)]
1324 #[should_panic(expected = "Defensive")]
1325 fn defensive_saturating_dec_panics() {
1326 let mut v = 0_u32;
1327 v.defensive_saturating_dec(); }
1329
1330 #[test]
1331 #[cfg(not(debug_assertions))]
1332 fn defensive_truncating_from_vec_defensive_works() {
1333 let unbound = vec![1u32, 2];
1334 let bound = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1335 assert_eq!(bound, vec![1u32]);
1336 }
1337
1338 #[test]
1339 #[cfg(not(debug_assertions))]
1340 fn defensive_truncating_from_slice_defensive_works() {
1341 let unbound = &[1u32, 2];
1342 let bound = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1343 assert_eq!(bound, &[1u32][..]);
1344 }
1345
1346 #[test]
1347 #[cfg(debug_assertions)]
1348 #[should_panic(
1349 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1350 )]
1351 fn defensive_truncating_from_vec_defensive_panics() {
1352 let unbound = vec![1u32, 2];
1353 let _ = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1354 }
1355
1356 #[test]
1357 #[cfg(debug_assertions)]
1358 #[should_panic(
1359 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1360 )]
1361 fn defensive_truncating_from_slice_defensive_panics() {
1362 let unbound = &[1u32, 2];
1363 let _ = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1364 }
1365
1366 #[test]
1367 fn defensive_truncate_from_vec_works() {
1368 let unbound = vec![1u32, 2, 3];
1369 let bound = BoundedVec::<u32, ConstU32<3>>::defensive_truncate_from(unbound.clone());
1370 assert_eq!(bound, unbound);
1371 }
1372
1373 #[test]
1374 fn defensive_truncate_from_slice_works() {
1375 let unbound = [1u32, 2, 3];
1376 let bound = BoundedSlice::<u32, ConstU32<3>>::defensive_truncate_from(&unbound);
1377 assert_eq!(bound, &unbound[..]);
1378 }
1379
1380 #[derive(Encode, Decode)]
1381 enum NestedType {
1382 Nested(Box<Self>),
1383 Done,
1384 }
1385
1386 #[test]
1387 fn test_opaque_wrapper_decode_limit() {
1388 let limit = sp_api::MAX_EXTRINSIC_DEPTH as usize;
1389 let mut ok_bytes = vec![0u8; limit];
1390 ok_bytes.push(1u8);
1391 let mut err_bytes = vec![0u8; limit + 1];
1392 err_bytes.push(1u8);
1393 assert!(<WrapperOpaque<NestedType>>::decode(&mut &ok_bytes.encode()[..]).is_ok());
1394 assert!(<WrapperOpaque<NestedType>>::decode(&mut &err_bytes.encode()[..]).is_err());
1395
1396 let ok_keep_opaque = WrapperKeepOpaque { data: ok_bytes, _phantom: PhantomData };
1397 let err_keep_opaque = WrapperKeepOpaque { data: err_bytes, _phantom: PhantomData };
1398
1399 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&ok_keep_opaque).is_some());
1400 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&err_keep_opaque).is_none());
1401 }
1402
1403 #[test]
1404 fn test_opaque_wrapper() {
1405 let encoded = WrapperOpaque(3u32).encode();
1406 assert_eq!(encoded, [codec::Compact(4u32).encode(), 3u32.to_le_bytes().to_vec()].concat());
1407 let vec_u8 = <Vec<u8>>::decode(&mut &encoded[..]).unwrap();
1408 let decoded_from_vec_u8 = u32::decode(&mut &vec_u8[..]).unwrap();
1409 assert_eq!(decoded_from_vec_u8, 3u32);
1410 let decoded = <WrapperOpaque<u32>>::decode(&mut &encoded[..]).unwrap();
1411 assert_eq!(decoded.0, 3u32);
1412
1413 assert_eq!(<WrapperOpaque<[u8; 63]>>::max_encoded_len(), 63 + 1);
1414 assert_eq!(
1415 <WrapperOpaque<[u8; 63]>>::max_encoded_len(),
1416 WrapperOpaque([0u8; 63]).encode().len()
1417 );
1418
1419 assert_eq!(<WrapperOpaque<[u8; 64]>>::max_encoded_len(), 64 + 2);
1420 assert_eq!(
1421 <WrapperOpaque<[u8; 64]>>::max_encoded_len(),
1422 WrapperOpaque([0u8; 64]).encode().len()
1423 );
1424
1425 assert_eq!(
1426 <WrapperOpaque<[u8; 2usize.pow(14) - 1]>>::max_encoded_len(),
1427 2usize.pow(14) - 1 + 2
1428 );
1429 assert_eq!(<WrapperOpaque<[u8; 2usize.pow(14)]>>::max_encoded_len(), 2usize.pow(14) + 4);
1430
1431 let data = 4u64;
1432 assert!(WrapperOpaque::<u32>::decode(&mut &data.encode().encode()[..]).is_err());
1434 }
1435
1436 #[test]
1437 fn test_keep_opaque_wrapper() {
1438 let data = 3u32.encode().encode();
1439
1440 let keep_opaque = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1441 keep_opaque.try_decode().unwrap();
1442
1443 let data = WrapperOpaque(50u32).encode();
1444 let decoded = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1445 let data = decoded.encode();
1446 WrapperOpaque::<u32>::decode(&mut &data[..]).unwrap();
1447 }
1448
1449 #[test]
1450 fn defensive_min_works() {
1451 assert_eq!(10, 10_u32.defensive_min(11_u32));
1452 assert_eq!(10, 10_u32.defensive_min(10_u32));
1453 }
1454
1455 #[test]
1456 #[cfg(debug_assertions)]
1457 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin\"")]
1458 fn defensive_min_panics() {
1459 10_u32.defensive_min(9_u32);
1460 }
1461
1462 #[test]
1463 fn defensive_strict_min_works() {
1464 assert_eq!(10, 10_u32.defensive_strict_min(11_u32));
1465 assert_eq!(9, 9_u32.defensive_strict_min(10_u32));
1466 }
1467
1468 #[test]
1469 #[cfg(debug_assertions)]
1470 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin strict\"")]
1471 fn defensive_strict_min_panics() {
1472 9_u32.defensive_strict_min(9_u32);
1473 }
1474
1475 #[test]
1476 fn defensive_max_works() {
1477 assert_eq!(11, 11_u32.defensive_max(10_u32));
1478 assert_eq!(10, 10_u32.defensive_max(10_u32));
1479 }
1480
1481 #[test]
1482 #[cfg(debug_assertions)]
1483 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax\"")]
1484 fn defensive_max_panics() {
1485 9_u32.defensive_max(10_u32);
1486 }
1487
1488 #[test]
1489 fn defensive_strict_max_works() {
1490 assert_eq!(11, 11_u32.defensive_strict_max(10_u32));
1491 assert_eq!(10, 10_u32.defensive_strict_max(9_u32));
1492 }
1493
1494 #[test]
1495 #[cfg(debug_assertions)]
1496 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax strict\"")]
1497 fn defensive_strict_max_panics() {
1498 9_u32.defensive_strict_max(9_u32);
1499 }
1500}