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, ConstInt, ConstU128, ConstU16,
32 ConstU32, ConstU64, ConstU8, ConstUint, 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 $crate::__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 $crate::__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 $crate::__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::ExtrinsicLike {
923 type Call;
924
925 fn call(&self) -> &Self::Call;
927}
928
929impl<Address, Call, Signature, Extra> ExtrinsicCall
930 for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
931where
932 Address: TypeInfo,
933 Call: TypeInfo,
934 Signature: TypeInfo,
935 Extra: TypeInfo,
936{
937 type Call = Call;
938
939 fn call(&self) -> &Call {
940 &self.function
941 }
942}
943
944pub trait InherentBuilder: ExtrinsicCall {
946 fn new_inherent(call: Self::Call) -> Self;
948}
949
950impl<Address, Call, Signature, Extra> InherentBuilder
951 for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
952where
953 Address: TypeInfo,
954 Call: TypeInfo,
955 Signature: TypeInfo,
956 Extra: TypeInfo,
957{
958 fn new_inherent(call: Self::Call) -> Self {
959 Self::new_bare(call)
960 }
961}
962
963pub trait SignedTransactionBuilder: ExtrinsicCall {
965 type Address;
966 type Signature;
967 type Extension;
968
969 fn new_signed_transaction(
972 call: Self::Call,
973 signed: Self::Address,
974 signature: Self::Signature,
975 tx_ext: Self::Extension,
976 ) -> Self;
977}
978
979impl<Address, Call, Signature, Extension> SignedTransactionBuilder
980 for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extension>
981where
982 Address: TypeInfo,
983 Call: TypeInfo,
984 Signature: TypeInfo,
985 Extension: TypeInfo,
986{
987 type Address = Address;
988 type Signature = Signature;
989 type Extension = Extension;
990
991 fn new_signed_transaction(
992 call: Self::Call,
993 signed: Address,
994 signature: Signature,
995 tx_ext: Extension,
996 ) -> Self {
997 Self::new_signed(call, signed, signature, tx_ext)
998 }
999}
1000
1001pub trait EstimateCallFee<Call, Balance> {
1005 fn estimate_call_fee(call: &Call, post_info: crate::dispatch::PostDispatchInfo) -> Balance;
1010}
1011
1012#[cfg(feature = "std")]
1014impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
1015 fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
1016 T.into()
1017 }
1018}
1019
1020#[derive(Debug, Eq, PartialEq, Default, Clone)]
1025#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
1026pub struct WrapperOpaque<T>(pub T);
1027
1028impl<T: Encode> EncodeLike for WrapperOpaque<T> {}
1029impl<T: Encode> EncodeLike<WrapperKeepOpaque<T>> for WrapperOpaque<T> {}
1030
1031impl<T: Encode> Encode for WrapperOpaque<T> {
1032 fn size_hint(&self) -> usize {
1033 self.0.size_hint().saturating_add(<codec::Compact<u32>>::max_encoded_len())
1034 }
1035
1036 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1037 self.0.encode().encode_to(dest);
1038 }
1039
1040 fn encode(&self) -> Vec<u8> {
1041 self.0.encode().encode()
1042 }
1043
1044 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1045 self.0.encode().using_encoded(f)
1046 }
1047}
1048
1049impl<T: Decode> Decode for WrapperOpaque<T> {
1050 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1051 Ok(Self(T::decode_all_with_depth_limit(
1052 sp_api::MAX_EXTRINSIC_DEPTH,
1053 &mut &<Vec<u8>>::decode(input)?[..],
1054 )?))
1055 }
1056
1057 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1058 <Vec<u8>>::skip(input)
1059 }
1060}
1061
1062impl<T> From<T> for WrapperOpaque<T> {
1063 fn from(t: T) -> Self {
1064 Self(t)
1065 }
1066}
1067
1068impl<T: MaxEncodedLen> MaxEncodedLen for WrapperOpaque<T> {
1069 fn max_encoded_len() -> usize {
1070 let t_max_len = T::max_encoded_len();
1071
1072 if t_max_len < 64 {
1074 t_max_len + 1
1075 } else if t_max_len < 2usize.pow(14) {
1076 t_max_len + 2
1077 } else if t_max_len < 2usize.pow(30) {
1078 t_max_len + 4
1079 } else {
1080 <codec::Compact<u32>>::max_encoded_len().saturating_add(T::max_encoded_len())
1081 }
1082 }
1083}
1084
1085impl<T: TypeInfo + 'static> TypeInfo for WrapperOpaque<T> {
1086 type Identity = Self;
1087 fn type_info() -> Type {
1088 Type::builder()
1089 .path(Path::new("WrapperOpaque", module_path!()))
1090 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1091 .composite(
1092 Fields::unnamed()
1093 .field(|f| f.compact::<u32>())
1094 .field(|f| f.ty::<T>().type_name("T")),
1095 )
1096 }
1097}
1098
1099#[derive(Debug, Eq, PartialEq, Default, Clone)]
1106pub struct WrapperKeepOpaque<T> {
1107 data: Vec<u8>,
1108 _phantom: core::marker::PhantomData<T>,
1109}
1110
1111impl<T: Decode> WrapperKeepOpaque<T> {
1112 pub fn try_decode(&self) -> Option<T> {
1116 T::decode_all_with_depth_limit(sp_api::MAX_EXTRINSIC_DEPTH, &mut &self.data[..]).ok()
1117 }
1118
1119 pub fn encoded_len(&self) -> usize {
1121 self.data.len()
1122 }
1123
1124 pub fn encoded(&self) -> &[u8] {
1126 &self.data
1127 }
1128
1129 pub fn from_encoded(data: Vec<u8>) -> Self {
1131 Self { data, _phantom: core::marker::PhantomData }
1132 }
1133}
1134
1135impl<T: Encode> EncodeLike for WrapperKeepOpaque<T> {}
1136impl<T: Encode> EncodeLike<WrapperOpaque<T>> for WrapperKeepOpaque<T> {}
1137
1138impl<T: Encode> Encode for WrapperKeepOpaque<T> {
1139 fn size_hint(&self) -> usize {
1140 self.data.len() + codec::Compact::<u32>::compact_len(&(self.data.len() as u32))
1141 }
1142
1143 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1144 self.data.encode_to(dest);
1145 }
1146
1147 fn encode(&self) -> Vec<u8> {
1148 self.data.encode()
1149 }
1150
1151 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1152 self.data.using_encoded(f)
1153 }
1154}
1155
1156impl<T: Decode> Decode for WrapperKeepOpaque<T> {
1157 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1158 Ok(Self { data: Vec::<u8>::decode(input)?, _phantom: core::marker::PhantomData })
1159 }
1160
1161 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1162 <Vec<u8>>::skip(input)
1163 }
1164}
1165
1166impl<T: MaxEncodedLen> MaxEncodedLen for WrapperKeepOpaque<T> {
1167 fn max_encoded_len() -> usize {
1168 WrapperOpaque::<T>::max_encoded_len()
1169 }
1170}
1171
1172impl<T: TypeInfo + 'static> TypeInfo for WrapperKeepOpaque<T> {
1173 type Identity = Self;
1174 fn type_info() -> Type {
1175 Type::builder()
1176 .path(Path::new("WrapperKeepOpaque", module_path!()))
1177 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1178 .composite(
1179 Fields::unnamed()
1180 .field(|f| f.compact::<u32>())
1181 .field(|f| f.ty::<T>().type_name("T")),
1182 )
1183 }
1184}
1185
1186pub trait PreimageProvider<Hash> {
1188 fn have_preimage(hash: &Hash) -> bool;
1192
1193 fn get_preimage(hash: &Hash) -> Option<Vec<u8>>;
1195
1196 fn preimage_requested(hash: &Hash) -> bool;
1198
1199 fn request_preimage(hash: &Hash);
1202
1203 fn unrequest_preimage(hash: &Hash);
1205}
1206
1207impl<Hash> PreimageProvider<Hash> for () {
1208 fn have_preimage(_: &Hash) -> bool {
1209 false
1210 }
1211 fn get_preimage(_: &Hash) -> Option<Vec<u8>> {
1212 None
1213 }
1214 fn preimage_requested(_: &Hash) -> bool {
1215 false
1216 }
1217 fn request_preimage(_: &Hash) {}
1218 fn unrequest_preimage(_: &Hash) {}
1219}
1220
1221pub trait PreimageRecipient<Hash>: PreimageProvider<Hash> {
1227 type MaxSize: Get<u32>;
1229
1230 fn note_preimage(bytes: crate::BoundedVec<u8, Self::MaxSize>);
1232
1233 fn unnote_preimage(hash: &Hash);
1237}
1238
1239impl<Hash> PreimageRecipient<Hash> for () {
1240 type MaxSize = ();
1241 fn note_preimage(_: crate::BoundedVec<u8, Self::MaxSize>) {}
1242 fn unnote_preimage(_: &Hash) {}
1243}
1244
1245pub trait AccountTouch<AssetId, AccountId> {
1254 type Balance;
1256
1257 fn deposit_required(asset: AssetId) -> Self::Balance;
1259
1260 fn should_touch(asset: AssetId, who: &AccountId) -> bool;
1262
1263 fn touch(asset: AssetId, who: &AccountId, depositor: &AccountId) -> DispatchResult;
1265}
1266
1267#[cfg(test)]
1268mod test {
1269 use super::*;
1270 use core::marker::PhantomData;
1271 use sp_core::bounded::{BoundedSlice, BoundedVec};
1272
1273 #[test]
1274 fn defensive_assert_works() {
1275 defensive_assert!(true);
1276 defensive_assert!(true,);
1277 defensive_assert!(true, "must work");
1278 defensive_assert!(true, "must work",);
1279 }
1280
1281 #[test]
1282 #[cfg(debug_assertions)]
1283 #[should_panic(expected = "Defensive failure has been triggered!: \"1 == 0\": \"Must fail\"")]
1284 fn defensive_assert_panics() {
1285 defensive_assert!(1 == 0, "Must fail");
1286 }
1287
1288 #[test]
1289 #[cfg(not(debug_assertions))]
1290 fn defensive_assert_does_not_panic() {
1291 defensive_assert!(1 == 0, "Must fail");
1292 }
1293
1294 #[test]
1295 #[cfg(not(debug_assertions))]
1296 fn defensive_saturating_accrue_works() {
1297 let mut v = 1_u32;
1298 v.defensive_saturating_accrue(2);
1299 assert_eq!(v, 3);
1300 v.defensive_saturating_accrue(u32::MAX);
1301 assert_eq!(v, u32::MAX);
1302 v.defensive_saturating_accrue(1);
1303 assert_eq!(v, u32::MAX);
1304 }
1305
1306 #[test]
1307 #[cfg(debug_assertions)]
1308 #[should_panic(expected = "Defensive")]
1309 fn defensive_saturating_accrue_panics() {
1310 let mut v = u32::MAX;
1311 v.defensive_saturating_accrue(1); }
1313
1314 #[test]
1315 #[cfg(not(debug_assertions))]
1316 fn defensive_saturating_reduce_works() {
1317 let mut v = u32::MAX;
1318 v.defensive_saturating_reduce(3);
1319 assert_eq!(v, u32::MAX - 3);
1320 v.defensive_saturating_reduce(u32::MAX);
1321 assert_eq!(v, 0);
1322 v.defensive_saturating_reduce(1);
1323 assert_eq!(v, 0);
1324 }
1325
1326 #[test]
1327 #[cfg(debug_assertions)]
1328 #[should_panic(expected = "Defensive")]
1329 fn defensive_saturating_reduce_panics() {
1330 let mut v = 0_u32;
1331 v.defensive_saturating_reduce(1); }
1333
1334 #[test]
1335 #[cfg(not(debug_assertions))]
1336 fn defensive_saturating_inc_works() {
1337 let mut v = 0_u32;
1338 for i in 1..10 {
1339 v.defensive_saturating_inc();
1340 assert_eq!(v, i);
1341 }
1342 v += u32::MAX - 10;
1343 v.defensive_saturating_inc();
1344 assert_eq!(v, u32::MAX);
1345 v.defensive_saturating_inc();
1346 assert_eq!(v, u32::MAX);
1347 }
1348
1349 #[test]
1350 #[cfg(debug_assertions)]
1351 #[should_panic(expected = "Defensive")]
1352 fn defensive_saturating_inc_panics() {
1353 let mut v = u32::MAX;
1354 v.defensive_saturating_inc(); }
1356
1357 #[test]
1358 #[cfg(not(debug_assertions))]
1359 fn defensive_saturating_dec_works() {
1360 let mut v = u32::MAX;
1361 for i in 1..10 {
1362 v.defensive_saturating_dec();
1363 assert_eq!(v, u32::MAX - i);
1364 }
1365 v -= u32::MAX - 10;
1366 v.defensive_saturating_dec();
1367 assert_eq!(v, 0);
1368 v.defensive_saturating_dec();
1369 assert_eq!(v, 0);
1370 }
1371
1372 #[test]
1373 #[cfg(debug_assertions)]
1374 #[should_panic(expected = "Defensive")]
1375 fn defensive_saturating_dec_panics() {
1376 let mut v = 0_u32;
1377 v.defensive_saturating_dec(); }
1379
1380 #[test]
1381 #[cfg(not(debug_assertions))]
1382 fn defensive_truncating_from_vec_defensive_works() {
1383 let unbound = vec![1u32, 2];
1384 let bound = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1385 assert_eq!(bound, vec![1u32]);
1386 }
1387
1388 #[test]
1389 #[cfg(not(debug_assertions))]
1390 fn defensive_truncating_from_slice_defensive_works() {
1391 let unbound = &[1u32, 2];
1392 let bound = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1393 assert_eq!(bound, &[1u32][..]);
1394 }
1395
1396 #[test]
1397 #[cfg(debug_assertions)]
1398 #[should_panic(
1399 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1400 )]
1401 fn defensive_truncating_from_vec_defensive_panics() {
1402 let unbound = vec![1u32, 2];
1403 let _ = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1404 }
1405
1406 #[test]
1407 #[cfg(debug_assertions)]
1408 #[should_panic(
1409 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1410 )]
1411 fn defensive_truncating_from_slice_defensive_panics() {
1412 let unbound = &[1u32, 2];
1413 let _ = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1414 }
1415
1416 #[test]
1417 fn defensive_truncate_from_vec_works() {
1418 let unbound = vec![1u32, 2, 3];
1419 let bound = BoundedVec::<u32, ConstU32<3>>::defensive_truncate_from(unbound.clone());
1420 assert_eq!(bound, unbound);
1421 }
1422
1423 #[test]
1424 fn defensive_truncate_from_slice_works() {
1425 let unbound = [1u32, 2, 3];
1426 let bound = BoundedSlice::<u32, ConstU32<3>>::defensive_truncate_from(&unbound);
1427 assert_eq!(bound, &unbound[..]);
1428 }
1429
1430 #[derive(Encode, Decode)]
1431 enum NestedType {
1432 Nested(Box<Self>),
1433 Done,
1434 }
1435
1436 #[test]
1437 fn test_opaque_wrapper_decode_limit() {
1438 let limit = sp_api::MAX_EXTRINSIC_DEPTH as usize;
1439 let mut ok_bytes = vec![0u8; limit];
1440 ok_bytes.push(1u8);
1441 let mut err_bytes = vec![0u8; limit + 1];
1442 err_bytes.push(1u8);
1443 assert!(<WrapperOpaque<NestedType>>::decode(&mut &ok_bytes.encode()[..]).is_ok());
1444 assert!(<WrapperOpaque<NestedType>>::decode(&mut &err_bytes.encode()[..]).is_err());
1445
1446 let ok_keep_opaque = WrapperKeepOpaque { data: ok_bytes, _phantom: PhantomData };
1447 let err_keep_opaque = WrapperKeepOpaque { data: err_bytes, _phantom: PhantomData };
1448
1449 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&ok_keep_opaque).is_some());
1450 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&err_keep_opaque).is_none());
1451 }
1452
1453 #[test]
1454 fn test_opaque_wrapper() {
1455 let encoded = WrapperOpaque(3u32).encode();
1456 assert_eq!(encoded, [codec::Compact(4u32).encode(), 3u32.to_le_bytes().to_vec()].concat());
1457 let vec_u8 = <Vec<u8>>::decode(&mut &encoded[..]).unwrap();
1458 let decoded_from_vec_u8 = u32::decode(&mut &vec_u8[..]).unwrap();
1459 assert_eq!(decoded_from_vec_u8, 3u32);
1460 let decoded = <WrapperOpaque<u32>>::decode(&mut &encoded[..]).unwrap();
1461 assert_eq!(decoded.0, 3u32);
1462
1463 assert_eq!(<WrapperOpaque<[u8; 63]>>::max_encoded_len(), 63 + 1);
1464 assert_eq!(
1465 <WrapperOpaque<[u8; 63]>>::max_encoded_len(),
1466 WrapperOpaque([0u8; 63]).encode().len()
1467 );
1468
1469 assert_eq!(<WrapperOpaque<[u8; 64]>>::max_encoded_len(), 64 + 2);
1470 assert_eq!(
1471 <WrapperOpaque<[u8; 64]>>::max_encoded_len(),
1472 WrapperOpaque([0u8; 64]).encode().len()
1473 );
1474
1475 assert_eq!(
1476 <WrapperOpaque<[u8; 2usize.pow(14) - 1]>>::max_encoded_len(),
1477 2usize.pow(14) - 1 + 2
1478 );
1479 assert_eq!(<WrapperOpaque<[u8; 2usize.pow(14)]>>::max_encoded_len(), 2usize.pow(14) + 4);
1480
1481 let data = 4u64;
1482 assert!(WrapperOpaque::<u32>::decode(&mut &data.encode().encode()[..]).is_err());
1484 }
1485
1486 #[test]
1487 fn test_keep_opaque_wrapper() {
1488 let data = 3u32.encode().encode();
1489
1490 let keep_opaque = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1491 keep_opaque.try_decode().unwrap();
1492
1493 let data = WrapperOpaque(50u32).encode();
1494 let decoded = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1495 let data = decoded.encode();
1496 WrapperOpaque::<u32>::decode(&mut &data[..]).unwrap();
1497 }
1498
1499 #[test]
1500 fn defensive_min_works() {
1501 assert_eq!(10, 10_u32.defensive_min(11_u32));
1502 assert_eq!(10, 10_u32.defensive_min(10_u32));
1503 }
1504
1505 #[test]
1506 #[cfg(debug_assertions)]
1507 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin\"")]
1508 fn defensive_min_panics() {
1509 10_u32.defensive_min(9_u32);
1510 }
1511
1512 #[test]
1513 fn defensive_strict_min_works() {
1514 assert_eq!(10, 10_u32.defensive_strict_min(11_u32));
1515 assert_eq!(9, 9_u32.defensive_strict_min(10_u32));
1516 }
1517
1518 #[test]
1519 #[cfg(debug_assertions)]
1520 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin strict\"")]
1521 fn defensive_strict_min_panics() {
1522 9_u32.defensive_strict_min(9_u32);
1523 }
1524
1525 #[test]
1526 fn defensive_max_works() {
1527 assert_eq!(11, 11_u32.defensive_max(10_u32));
1528 assert_eq!(10, 10_u32.defensive_max(10_u32));
1529 }
1530
1531 #[test]
1532 #[cfg(debug_assertions)]
1533 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax\"")]
1534 fn defensive_max_panics() {
1535 9_u32.defensive_max(10_u32);
1536 }
1537
1538 #[test]
1539 fn defensive_strict_max_works() {
1540 assert_eq!(11, 11_u32.defensive_strict_max(10_u32));
1541 assert_eq!(10, 10_u32.defensive_strict_max(9_u32));
1542 }
1543
1544 #[test]
1545 #[cfg(debug_assertions)]
1546 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax strict\"")]
1547 fn defensive_strict_max_panics() {
1548 9_u32.defensive_strict_max(9_u32);
1549 }
1550}