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::{
35 traits::{Block as BlockT, ExtrinsicCall},
36 DispatchError,
37};
38
39#[doc(hidden)]
40pub const DEFENSIVE_OP_PUBLIC_ERROR: &str = "a defensive failure has been triggered; please report the block number at https://github.com/paritytech/polkadot-sdk/issues";
41#[doc(hidden)]
42pub const DEFENSIVE_OP_INTERNAL_ERROR: &str = "Defensive failure has been triggered!";
43
44pub trait VariantCount {
46 const VARIANT_COUNT: u32;
48}
49
50impl VariantCount for () {
51 const VARIANT_COUNT: u32 = 0;
52}
53
54impl VariantCount for u8 {
55 const VARIANT_COUNT: u32 = 256;
56}
57
58pub struct VariantCountOf<T: VariantCount>(core::marker::PhantomData<T>);
60impl<T: VariantCount> Get<u32> for VariantCountOf<T> {
61 fn get() -> u32 {
62 T::VARIANT_COUNT
63 }
64}
65
66#[macro_export]
70macro_rules! defensive {
71 () => {
72 $crate::__private::log::error!(
73 target: "runtime::defensive",
74 "{}",
75 $crate::traits::DEFENSIVE_OP_PUBLIC_ERROR
76 );
77 debug_assert!(false, "{}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR);
78 };
79 ($error:expr $(,)?) => {
80 $crate::__private::log::error!(
81 target: "runtime::defensive",
82 "{}: {:?}",
83 $crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
84 $error
85 );
86 debug_assert!(false, "{}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error);
87 };
88 ($error:expr, $proof:expr $(,)?) => {
89 $crate::__private::log::error!(
90 target: "runtime::defensive",
91 "{}: {:?}: {:?}",
92 $crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
93 $error,
94 $proof,
95 );
96 debug_assert!(false, "{}: {:?}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error, $proof);
97 }
98}
99
100#[macro_export]
111macro_rules! defensive_assert {
112 ($cond:expr $(, $proof:expr )? $(,)?) => {
113 if !($cond) {
114 $crate::defensive!(::core::stringify!($cond) $(, $proof )?);
115 }
116 };
117}
118
119pub mod defensive_prelude {
121 pub use super::{Defensive, DefensiveOption, DefensiveResult};
122}
123
124pub trait Defensive<T> {
142 fn defensive_unwrap_or(self, other: T) -> T;
145
146 fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T;
149
150 fn defensive_unwrap_or_default(self) -> T
153 where
154 T: Default;
155
156 fn defensive(self) -> Self;
168
169 fn defensive_proof(self, proof: &'static str) -> Self;
172}
173
174pub trait DefensiveResult<T, E> {
176 fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F>;
179
180 fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;
183
184 fn defensive_ok(self) -> Option<T>;
187
188 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E>;
191}
192
193pub trait DefensiveOption<T> {
195 fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;
198
199 fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E>;
202
203 fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E>;
205
206 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U>;
209}
210
211impl<T> Defensive<T> for Option<T> {
212 fn defensive_unwrap_or(self, or: T) -> T {
213 match self {
214 Some(inner) => inner,
215 None => {
216 defensive!();
217 or
218 },
219 }
220 }
221
222 fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
223 match self {
224 Some(inner) => inner,
225 None => {
226 defensive!();
227 f()
228 },
229 }
230 }
231
232 fn defensive_unwrap_or_default(self) -> T
233 where
234 T: Default,
235 {
236 match self {
237 Some(inner) => inner,
238 None => {
239 defensive!();
240 Default::default()
241 },
242 }
243 }
244
245 fn defensive(self) -> Self {
246 match self {
247 Some(inner) => Some(inner),
248 None => {
249 defensive!();
250 None
251 },
252 }
253 }
254
255 fn defensive_proof(self, proof: &'static str) -> Self {
256 if self.is_none() {
257 defensive!(proof);
258 }
259 self
260 }
261}
262
263impl<T, E: core::fmt::Debug> Defensive<T> for Result<T, E> {
264 fn defensive_unwrap_or(self, or: T) -> T {
265 match self {
266 Ok(inner) => inner,
267 Err(e) => {
268 defensive!(e);
269 or
270 },
271 }
272 }
273
274 fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
275 match self {
276 Ok(inner) => inner,
277 Err(e) => {
278 defensive!(e);
279 f()
280 },
281 }
282 }
283
284 fn defensive_unwrap_or_default(self) -> T
285 where
286 T: Default,
287 {
288 match self {
289 Ok(inner) => inner,
290 Err(e) => {
291 defensive!(e);
292 Default::default()
293 },
294 }
295 }
296
297 fn defensive(self) -> Self {
298 match self {
299 Ok(inner) => Ok(inner),
300 Err(e) => {
301 defensive!(e);
302 Err(e)
303 },
304 }
305 }
306
307 fn defensive_proof(self, proof: &'static str) -> Self {
308 match self {
309 Ok(inner) => Ok(inner),
310 Err(e) => {
311 defensive!(e, proof);
312 Err(e)
313 },
314 }
315 }
316}
317
318impl<T, E: core::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
319 fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F> {
320 self.map_err(|e| {
321 defensive!(e);
322 o(e)
323 })
324 }
325
326 fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
327 self.map_or_else(
328 |e| {
329 defensive!(e);
330 default(e)
331 },
332 f,
333 )
334 }
335
336 fn defensive_ok(self) -> Option<T> {
337 match self {
338 Ok(inner) => Some(inner),
339 Err(e) => {
340 defensive!(e);
341 None
342 },
343 }
344 }
345
346 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E> {
347 match self {
348 Ok(inner) => Ok(f(inner)),
349 Err(e) => {
350 defensive!(e);
351 Err(e)
352 },
353 }
354 }
355}
356
357impl<T> DefensiveOption<T> for Option<T> {
358 fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
359 self.map_or_else(
360 || {
361 defensive!();
362 default()
363 },
364 f,
365 )
366 }
367
368 fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
369 self.ok_or_else(|| {
370 let err_value = err();
371 defensive!(err_value);
372 err_value
373 })
374 }
375
376 fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E> {
377 self.ok_or_else(|| {
378 defensive!(err);
379 err
380 })
381 }
382
383 fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
384 match self {
385 Some(inner) => Some(f(inner)),
386 None => {
387 defensive!();
388 None
389 },
390 }
391 }
392}
393
394pub trait DefensiveSaturating {
397 fn defensive_saturating_add(self, other: Self) -> Self;
399 fn defensive_saturating_sub(self, other: Self) -> Self;
401 fn defensive_saturating_mul(self, other: Self) -> Self;
403 fn defensive_saturating_accrue(&mut self, other: Self);
405 fn defensive_saturating_reduce(&mut self, other: Self);
407 fn defensive_saturating_inc(&mut self);
409 fn defensive_saturating_dec(&mut self);
411}
412
413impl<T: Saturating + CheckedAdd + CheckedMul + CheckedSub + One> DefensiveSaturating for T {
416 fn defensive_saturating_add(self, other: Self) -> Self {
417 self.checked_add(&other).defensive_unwrap_or_else(|| self.saturating_add(other))
418 }
419 fn defensive_saturating_sub(self, other: Self) -> Self {
420 self.checked_sub(&other).defensive_unwrap_or_else(|| self.saturating_sub(other))
421 }
422 fn defensive_saturating_mul(self, other: Self) -> Self {
423 self.checked_mul(&other).defensive_unwrap_or_else(|| self.saturating_mul(other))
424 }
425 fn defensive_saturating_accrue(&mut self, other: Self) {
426 *self = core::mem::replace(self, One::one()).defensive_saturating_add(other);
428 }
429 fn defensive_saturating_reduce(&mut self, other: Self) {
430 *self = core::mem::replace(self, One::one()).defensive_saturating_sub(other);
432 }
433 fn defensive_saturating_inc(&mut self) {
434 self.defensive_saturating_accrue(One::one());
435 }
436 fn defensive_saturating_dec(&mut self) {
437 self.defensive_saturating_reduce(One::one());
438 }
439}
440
441pub trait DefensiveTruncateFrom<T> {
443 fn defensive_truncate_from(unbound: T) -> Self;
457}
458
459impl<T, U> DefensiveTruncateFrom<U> for T
460where
461 T: TruncateFrom<U> + TryFrom<U, Error = U>,
466{
467 fn defensive_truncate_from(unbound: U) -> Self {
468 unbound.try_into().map_or_else(
469 |err| {
470 defensive!("DefensiveTruncateFrom truncating");
471 T::truncate_from(err)
472 },
473 |bound| bound,
474 )
475 }
476}
477
478pub trait DefensiveTruncateInto<T> {
480 fn defensive_truncate_into(self) -> T;
482}
483
484impl<T, U: DefensiveTruncateFrom<T>> DefensiveTruncateInto<U> for T {
485 fn defensive_truncate_into(self) -> U {
486 U::defensive_truncate_from(self)
487 }
488}
489pub trait DefensiveMin<T> {
493 fn defensive_min(self, other: T) -> Self;
511
512 fn defensive_strict_min(self, other: T) -> Self;
528}
529
530impl<T> DefensiveMin<T> for T
531where
532 T: PartialOrd<T>,
533{
534 fn defensive_min(self, other: T) -> Self {
535 if self <= other {
536 self
537 } else {
538 defensive!("DefensiveMin");
539 other
540 }
541 }
542
543 fn defensive_strict_min(self, other: T) -> Self {
544 if self < other {
545 self
546 } else {
547 defensive!("DefensiveMin strict");
548 other
549 }
550 }
551}
552
553pub trait DefensiveMax<T> {
557 fn defensive_max(self, other: T) -> Self;
575
576 fn defensive_strict_max(self, other: T) -> Self;
592}
593
594impl<T> DefensiveMax<T> for T
595where
596 T: PartialOrd<T>,
597{
598 fn defensive_max(self, other: T) -> Self {
599 if self >= other {
600 self
601 } else {
602 defensive!("DefensiveMax");
603 other
604 }
605 }
606
607 fn defensive_strict_max(self, other: T) -> Self {
608 if self > other {
609 self
610 } else {
611 defensive!("DefensiveMax strict");
612 other
613 }
614 }
615}
616
617pub trait Len {
619 fn len(&self) -> usize;
621}
622
623impl<T: IntoIterator + Clone> Len for T
624where
625 <T as IntoIterator>::IntoIter: ExactSizeIterator,
626{
627 fn len(&self) -> usize {
628 self.clone().into_iter().len()
629 }
630}
631
632pub trait TryDrop: Sized {
634 fn try_drop(self) -> Result<(), Self>;
636}
637
638impl TryDrop for () {
639 fn try_drop(self) -> Result<(), Self> {
640 Ok(())
641 }
642}
643
644pub enum SameOrOther<A, B> {
648 None,
650 Same(A),
652 Other(B),
654}
655
656impl<A, B> TryDrop for SameOrOther<A, B> {
657 fn try_drop(self) -> Result<(), Self> {
658 if let SameOrOther::None = self {
659 Ok(())
660 } else {
661 Err(self)
662 }
663 }
664}
665
666impl<A, B> SameOrOther<A, B> {
667 pub fn try_same(self) -> Result<A, Self> {
670 match self {
671 SameOrOther::Same(a) => Ok(a),
672 x => Err(x),
673 }
674 }
675
676 pub fn try_other(self) -> Result<B, Self> {
679 match self {
680 SameOrOther::Other(b) => Ok(b),
681 x => Err(x),
682 }
683 }
684
685 pub fn try_none(self) -> Result<(), Self> {
687 match self {
688 SameOrOther::None => Ok(()),
689 x => Err(x),
690 }
691 }
692
693 pub fn same(self) -> Result<A, B>
694 where
695 A: Default,
696 {
697 match self {
698 SameOrOther::Same(a) => Ok(a),
699 SameOrOther::None => Ok(A::default()),
700 SameOrOther::Other(b) => Err(b),
701 }
702 }
703
704 pub fn other(self) -> Result<B, A>
705 where
706 B: Default,
707 {
708 match self {
709 SameOrOther::Same(a) => Err(a),
710 SameOrOther::None => Ok(B::default()),
711 SameOrOther::Other(b) => Ok(b),
712 }
713 }
714}
715
716#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
718#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
719#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
720pub trait OnNewAccount<AccountId> {
721 fn on_new_account(who: &AccountId);
723}
724
725#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
727#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
728#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
729pub trait OnKilledAccount<AccountId> {
730 fn on_killed_account(who: &AccountId);
732}
733
734pub trait HandleLifetime<T> {
736 fn created(_t: &T) -> Result<(), DispatchError> {
738 Ok(())
739 }
740
741 fn killed(_t: &T) -> Result<(), DispatchError> {
743 Ok(())
744 }
745}
746
747impl<T> HandleLifetime<T> for () {}
748
749pub trait Time {
750 type Moment: sp_arithmetic::traits::AtLeast32Bit + Parameter + Default + Copy + MaxEncodedLen;
751
752 fn now() -> Self::Moment;
753}
754
755pub trait UnixTime {
757 fn now() -> core::time::Duration;
759}
760
761pub trait IsType<T>: Into<T> + From<T> {
765 fn from_ref(t: &T) -> &Self;
767
768 fn into_ref(&self) -> &T;
770
771 fn from_mut(t: &mut T) -> &mut Self;
773
774 fn into_mut(&mut self) -> &mut T;
776}
777
778impl<T> IsType<T> for T {
779 fn from_ref(t: &T) -> &Self {
780 t
781 }
782 fn into_ref(&self) -> &T {
783 self
784 }
785 fn from_mut(t: &mut T) -> &mut Self {
786 t
787 }
788 fn into_mut(&mut self) -> &mut T {
789 self
790 }
791}
792
793pub trait IsSubType<T> {
836 fn is_sub_type(&self) -> Option<&T>;
838}
839
840pub trait ExecuteBlock<Block: BlockT> {
845 fn execute_block(mut block: Block::LazyBlock) {
858 Self::verify_and_remove_seal(&mut block);
859 Self::execute_verified_block(block);
860 }
861
862 fn verify_and_remove_seal(block: &mut Block::LazyBlock);
871
872 fn execute_verified_block(block: Block::LazyBlock);
878}
879
880pub trait PrivilegeCmp<Origin> {
882 fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering>;
888}
889
890pub struct EqualPrivilegeOnly;
894impl<Origin: PartialEq> PrivilegeCmp<Origin> for EqualPrivilegeOnly {
895 fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering> {
896 (left == right).then(|| Ordering::Equal)
897 }
898}
899
900#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
911#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
912#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
913pub trait OffchainWorker<BlockNumber> {
914 fn offchain_worker(_n: BlockNumber) {}
921}
922
923pub struct Backing {
926 pub approvals: u32,
928 pub eligible: u32,
930}
931
932pub trait GetBacking {
934 fn get_backing(&self) -> Option<Backing>;
937}
938
939pub trait IsInherent<Extrinsic> {
941 fn is_inherent(ext: &Extrinsic) -> bool;
943}
944
945pub trait InherentBuilder: ExtrinsicCall {
947 fn new_inherent(call: Self::Call) -> Self;
949}
950
951impl<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions> InherentBuilder
952 for sp_runtime::generic::UncheckedExtrinsic<
953 Address,
954 Call,
955 Signature,
956 ExtensionV0,
957 ExtensionOtherVersions,
958 >
959{
960 fn new_inherent(call: Self::Call) -> Self {
961 Self::new_bare(call)
962 }
963}
964
965pub trait SignedTransactionBuilder: ExtrinsicCall {
967 type Address;
968 type Signature;
969 type Extension;
970
971 fn new_signed_transaction(
974 call: Self::Call,
975 signed: Self::Address,
976 signature: Self::Signature,
977 tx_ext: Self::Extension,
978 ) -> Self;
979}
980
981impl<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions> SignedTransactionBuilder
982 for sp_runtime::generic::UncheckedExtrinsic<
983 Address,
984 Call,
985 Signature,
986 ExtensionV0,
987 ExtensionOtherVersions,
988 >
989{
990 type Address = Address;
991 type Signature = Signature;
992 type Extension = ExtensionV0;
993
994 fn new_signed_transaction(
995 call: Self::Call,
996 signed: Address,
997 signature: Signature,
998 tx_ext: ExtensionV0,
999 ) -> Self {
1000 Self::new_signed(call, signed, signature, tx_ext)
1001 }
1002}
1003
1004pub trait EstimateCallFee<Call, Balance> {
1008 fn estimate_call_fee(call: &Call, post_info: crate::dispatch::PostDispatchInfo) -> Balance;
1013}
1014
1015pub trait EstimateFee<Balance> {
1023 fn estimate_fee(len: u32, info: &crate::dispatch::DispatchInfo) -> Balance;
1025}
1026
1027#[cfg(feature = "std")]
1029impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
1030 fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
1031 T.into()
1032 }
1033}
1034
1035#[cfg(feature = "std")]
1036impl<Call, Balance: From<u32>, const T: u64> EstimateCallFee<Call, Balance> for ConstU64<T> {
1037 fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
1038 (T as u32).into()
1039 }
1040}
1041
1042#[cfg(feature = "std")]
1043impl<Balance: From<u32>, const T: u32> EstimateFee<Balance> for ConstU32<T> {
1044 fn estimate_fee(_: u32, _: &crate::dispatch::DispatchInfo) -> Balance {
1045 T.into()
1046 }
1047}
1048
1049#[cfg(feature = "std")]
1050impl<Balance: From<u32>, const T: u64> EstimateFee<Balance> for ConstU64<T> {
1051 fn estimate_fee(_: u32, _: &crate::dispatch::DispatchInfo) -> Balance {
1052 (T as u32).into()
1053 }
1054}
1055
1056#[derive(Debug, Eq, PartialEq, Default, Clone)]
1061#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
1062pub struct WrapperOpaque<T>(pub T);
1063
1064impl<T: Encode> EncodeLike for WrapperOpaque<T> {}
1065impl<T: Encode> EncodeLike<WrapperKeepOpaque<T>> for WrapperOpaque<T> {}
1066
1067impl<T: Encode> Encode for WrapperOpaque<T> {
1068 fn size_hint(&self) -> usize {
1069 self.0.size_hint().saturating_add(<codec::Compact<u32>>::max_encoded_len())
1070 }
1071
1072 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1073 self.0.encode().encode_to(dest);
1074 }
1075
1076 fn encode(&self) -> Vec<u8> {
1077 self.0.encode().encode()
1078 }
1079
1080 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1081 self.0.encode().using_encoded(f)
1082 }
1083}
1084
1085impl<T: Decode> Decode for WrapperOpaque<T> {
1086 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1087 Ok(Self(T::decode_all_with_depth_limit(
1088 crate::MAX_EXTRINSIC_DEPTH,
1089 &mut &<Vec<u8>>::decode(input)?[..],
1090 )?))
1091 }
1092
1093 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1094 <Vec<u8>>::skip(input)
1095 }
1096}
1097
1098impl<T> From<T> for WrapperOpaque<T> {
1099 fn from(t: T) -> Self {
1100 Self(t)
1101 }
1102}
1103
1104impl<T: MaxEncodedLen> MaxEncodedLen for WrapperOpaque<T> {
1105 fn max_encoded_len() -> usize {
1106 let t_max_len = T::max_encoded_len();
1107
1108 if t_max_len < 64 {
1110 t_max_len + 1
1111 } else if t_max_len < 2usize.pow(14) {
1112 t_max_len + 2
1113 } else if t_max_len < 2usize.pow(30) {
1114 t_max_len + 4
1115 } else {
1116 <codec::Compact<u32>>::max_encoded_len().saturating_add(T::max_encoded_len())
1117 }
1118 }
1119}
1120
1121impl<T: TypeInfo + 'static> TypeInfo for WrapperOpaque<T> {
1122 type Identity = Self;
1123 fn type_info() -> Type {
1124 Type::builder()
1125 .path(Path::new("WrapperOpaque", module_path!()))
1126 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1127 .composite(
1128 Fields::unnamed()
1129 .field(|f| f.compact::<u32>())
1130 .field(|f| f.ty::<T>().type_name("T")),
1131 )
1132 }
1133}
1134
1135#[derive(Debug, Eq, PartialEq, Default, Clone)]
1142pub struct WrapperKeepOpaque<T> {
1143 data: Vec<u8>,
1144 _phantom: core::marker::PhantomData<T>,
1145}
1146
1147impl<T: Decode> WrapperKeepOpaque<T> {
1148 pub fn try_decode(&self) -> Option<T> {
1152 T::decode_all_with_depth_limit(crate::MAX_EXTRINSIC_DEPTH, &mut &self.data[..]).ok()
1153 }
1154
1155 pub fn encoded_len(&self) -> usize {
1157 self.data.len()
1158 }
1159
1160 pub fn encoded(&self) -> &[u8] {
1162 &self.data
1163 }
1164
1165 pub fn from_encoded(data: Vec<u8>) -> Self {
1167 Self { data, _phantom: core::marker::PhantomData }
1168 }
1169}
1170
1171impl<T: Encode> EncodeLike for WrapperKeepOpaque<T> {}
1172impl<T: Encode> EncodeLike<WrapperOpaque<T>> for WrapperKeepOpaque<T> {}
1173
1174impl<T: Encode> Encode for WrapperKeepOpaque<T> {
1175 fn size_hint(&self) -> usize {
1176 self.data.len() + codec::Compact::<u32>::compact_len(&(self.data.len() as u32))
1177 }
1178
1179 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1180 self.data.encode_to(dest);
1181 }
1182
1183 fn encode(&self) -> Vec<u8> {
1184 self.data.encode()
1185 }
1186
1187 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1188 self.data.using_encoded(f)
1189 }
1190}
1191
1192impl<T: Decode> Decode for WrapperKeepOpaque<T> {
1193 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1194 Ok(Self { data: Vec::<u8>::decode(input)?, _phantom: core::marker::PhantomData })
1195 }
1196
1197 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1198 <Vec<u8>>::skip(input)
1199 }
1200}
1201
1202impl<T: MaxEncodedLen> MaxEncodedLen for WrapperKeepOpaque<T> {
1203 fn max_encoded_len() -> usize {
1204 WrapperOpaque::<T>::max_encoded_len()
1205 }
1206}
1207
1208impl<T: TypeInfo + 'static> TypeInfo for WrapperKeepOpaque<T> {
1209 type Identity = Self;
1210 fn type_info() -> Type {
1211 Type::builder()
1212 .path(Path::new("WrapperKeepOpaque", module_path!()))
1213 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1214 .composite(
1215 Fields::unnamed()
1216 .field(|f| f.compact::<u32>())
1217 .field(|f| f.ty::<T>().type_name("T")),
1218 )
1219 }
1220}
1221
1222pub trait PreimageProvider<Hash> {
1224 fn have_preimage(hash: &Hash) -> bool;
1228
1229 fn get_preimage(hash: &Hash) -> Option<Vec<u8>>;
1231
1232 fn preimage_requested(hash: &Hash) -> bool;
1234
1235 fn request_preimage(hash: &Hash);
1238
1239 fn unrequest_preimage(hash: &Hash);
1241}
1242
1243impl<Hash> PreimageProvider<Hash> for () {
1244 fn have_preimage(_: &Hash) -> bool {
1245 false
1246 }
1247 fn get_preimage(_: &Hash) -> Option<Vec<u8>> {
1248 None
1249 }
1250 fn preimage_requested(_: &Hash) -> bool {
1251 false
1252 }
1253 fn request_preimage(_: &Hash) {}
1254 fn unrequest_preimage(_: &Hash) {}
1255}
1256
1257pub trait PreimageRecipient<Hash>: PreimageProvider<Hash> {
1263 type MaxSize: Get<u32>;
1265
1266 fn note_preimage(bytes: crate::BoundedVec<u8, Self::MaxSize>);
1268
1269 fn unnote_preimage(hash: &Hash);
1273}
1274
1275impl<Hash> PreimageRecipient<Hash> for () {
1276 type MaxSize = ();
1277 fn note_preimage(_: crate::BoundedVec<u8, Self::MaxSize>) {}
1278 fn unnote_preimage(_: &Hash) {}
1279}
1280
1281pub trait AccountTouch<AssetId, AccountId> {
1290 type Balance;
1292
1293 fn deposit_required(asset: AssetId) -> Self::Balance;
1295
1296 fn should_touch(asset: AssetId, who: &AccountId) -> bool;
1298
1299 fn touch(asset: AssetId, who: &AccountId, depositor: &AccountId) -> DispatchResult;
1301}
1302
1303pub trait RewardsReporter<ValidatorId> {
1305 fn reward_by_ids(validators_points: impl IntoIterator<Item = (ValidatorId, u32)>);
1308}
1309
1310impl RewardsReporter<sp_runtime::AccountId32> for () {
1311 fn reward_by_ids(_validators_points: impl IntoIterator<Item = (sp_runtime::AccountId32, u32)>) {
1312 }
1314}
1315#[cfg(test)]
1316mod test {
1317 use super::*;
1318 use core::marker::PhantomData;
1319 use sp_core::bounded::{BoundedSlice, BoundedVec};
1320
1321 #[test]
1322 fn defensive_assert_works() {
1323 defensive_assert!(true);
1324 defensive_assert!(true,);
1325 defensive_assert!(true, "must work");
1326 defensive_assert!(true, "must work",);
1327 }
1328
1329 #[test]
1330 #[cfg(debug_assertions)]
1331 #[should_panic(expected = "Defensive failure has been triggered!: \"1 == 0\": \"Must fail\"")]
1332 fn defensive_assert_panics() {
1333 defensive_assert!(1 == 0, "Must fail");
1334 }
1335
1336 #[test]
1337 #[cfg(not(debug_assertions))]
1338 fn defensive_assert_does_not_panic() {
1339 defensive_assert!(1 == 0, "Must fail");
1340 }
1341
1342 #[test]
1343 #[cfg(not(debug_assertions))]
1344 fn defensive_saturating_accrue_works() {
1345 let mut v = 1_u32;
1346 v.defensive_saturating_accrue(2);
1347 assert_eq!(v, 3);
1348 v.defensive_saturating_accrue(u32::MAX);
1349 assert_eq!(v, u32::MAX);
1350 v.defensive_saturating_accrue(1);
1351 assert_eq!(v, u32::MAX);
1352 }
1353
1354 #[test]
1355 #[cfg(debug_assertions)]
1356 #[should_panic(expected = "Defensive")]
1357 fn defensive_saturating_accrue_panics() {
1358 let mut v = u32::MAX;
1359 v.defensive_saturating_accrue(1); }
1361
1362 #[test]
1363 #[cfg(not(debug_assertions))]
1364 fn defensive_saturating_reduce_works() {
1365 let mut v = u32::MAX;
1366 v.defensive_saturating_reduce(3);
1367 assert_eq!(v, u32::MAX - 3);
1368 v.defensive_saturating_reduce(u32::MAX);
1369 assert_eq!(v, 0);
1370 v.defensive_saturating_reduce(1);
1371 assert_eq!(v, 0);
1372 }
1373
1374 #[test]
1375 #[cfg(debug_assertions)]
1376 #[should_panic(expected = "Defensive")]
1377 fn defensive_saturating_reduce_panics() {
1378 let mut v = 0_u32;
1379 v.defensive_saturating_reduce(1); }
1381
1382 #[test]
1383 #[cfg(not(debug_assertions))]
1384 fn defensive_saturating_inc_works() {
1385 let mut v = 0_u32;
1386 for i in 1..10 {
1387 v.defensive_saturating_inc();
1388 assert_eq!(v, i);
1389 }
1390 v += u32::MAX - 10;
1391 v.defensive_saturating_inc();
1392 assert_eq!(v, u32::MAX);
1393 v.defensive_saturating_inc();
1394 assert_eq!(v, u32::MAX);
1395 }
1396
1397 #[test]
1398 #[cfg(debug_assertions)]
1399 #[should_panic(expected = "Defensive")]
1400 fn defensive_saturating_inc_panics() {
1401 let mut v = u32::MAX;
1402 v.defensive_saturating_inc(); }
1404
1405 #[test]
1406 #[cfg(not(debug_assertions))]
1407 fn defensive_saturating_dec_works() {
1408 let mut v = u32::MAX;
1409 for i in 1..10 {
1410 v.defensive_saturating_dec();
1411 assert_eq!(v, u32::MAX - i);
1412 }
1413 v -= u32::MAX - 10;
1414 v.defensive_saturating_dec();
1415 assert_eq!(v, 0);
1416 v.defensive_saturating_dec();
1417 assert_eq!(v, 0);
1418 }
1419
1420 #[test]
1421 #[cfg(debug_assertions)]
1422 #[should_panic(expected = "Defensive")]
1423 fn defensive_saturating_dec_panics() {
1424 let mut v = 0_u32;
1425 v.defensive_saturating_dec(); }
1427
1428 #[test]
1429 #[cfg(not(debug_assertions))]
1430 fn defensive_truncating_from_vec_defensive_works() {
1431 let unbound = vec![1u32, 2];
1432 let bound = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1433 assert_eq!(bound, vec![1u32]);
1434 }
1435
1436 #[test]
1437 #[cfg(not(debug_assertions))]
1438 fn defensive_truncating_from_slice_defensive_works() {
1439 let unbound = &[1u32, 2];
1440 let bound = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1441 assert_eq!(bound, &[1u32][..]);
1442 }
1443
1444 #[test]
1445 #[cfg(debug_assertions)]
1446 #[should_panic(
1447 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1448 )]
1449 fn defensive_truncating_from_vec_defensive_panics() {
1450 let unbound = vec![1u32, 2];
1451 let _ = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1452 }
1453
1454 #[test]
1455 #[cfg(debug_assertions)]
1456 #[should_panic(
1457 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1458 )]
1459 fn defensive_truncating_from_slice_defensive_panics() {
1460 let unbound = &[1u32, 2];
1461 let _ = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1462 }
1463
1464 #[test]
1465 fn defensive_truncate_from_vec_works() {
1466 let unbound = vec![1u32, 2, 3];
1467 let bound = BoundedVec::<u32, ConstU32<3>>::defensive_truncate_from(unbound.clone());
1468 assert_eq!(bound, unbound);
1469 }
1470
1471 #[test]
1472 fn defensive_truncate_from_slice_works() {
1473 let unbound = [1u32, 2, 3];
1474 let bound = BoundedSlice::<u32, ConstU32<3>>::defensive_truncate_from(&unbound);
1475 assert_eq!(bound, &unbound[..]);
1476 }
1477
1478 #[derive(Encode, Decode)]
1479 enum NestedType {
1480 Nested(Box<Self>),
1481 Done,
1482 }
1483
1484 #[test]
1485 fn test_opaque_wrapper_decode_limit() {
1486 let limit = crate::MAX_EXTRINSIC_DEPTH as usize;
1487 let mut ok_bytes = vec![0u8; limit];
1488 ok_bytes.push(1u8);
1489 let mut err_bytes = vec![0u8; limit + 1];
1490 err_bytes.push(1u8);
1491 assert!(<WrapperOpaque<NestedType>>::decode(&mut &ok_bytes.encode()[..]).is_ok());
1492 assert!(<WrapperOpaque<NestedType>>::decode(&mut &err_bytes.encode()[..]).is_err());
1493
1494 let ok_keep_opaque = WrapperKeepOpaque { data: ok_bytes, _phantom: PhantomData };
1495 let err_keep_opaque = WrapperKeepOpaque { data: err_bytes, _phantom: PhantomData };
1496
1497 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&ok_keep_opaque).is_some());
1498 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&err_keep_opaque).is_none());
1499 }
1500
1501 #[test]
1502 fn test_opaque_wrapper() {
1503 let encoded = WrapperOpaque(3u32).encode();
1504 assert_eq!(encoded, [codec::Compact(4u32).encode(), 3u32.to_le_bytes().to_vec()].concat());
1505 let vec_u8 = <Vec<u8>>::decode(&mut &encoded[..]).unwrap();
1506 let decoded_from_vec_u8 = u32::decode(&mut &vec_u8[..]).unwrap();
1507 assert_eq!(decoded_from_vec_u8, 3u32);
1508 let decoded = <WrapperOpaque<u32>>::decode(&mut &encoded[..]).unwrap();
1509 assert_eq!(decoded.0, 3u32);
1510
1511 assert_eq!(<WrapperOpaque<[u8; 63]>>::max_encoded_len(), 63 + 1);
1512 assert_eq!(
1513 <WrapperOpaque<[u8; 63]>>::max_encoded_len(),
1514 WrapperOpaque([0u8; 63]).encode().len()
1515 );
1516
1517 assert_eq!(<WrapperOpaque<[u8; 64]>>::max_encoded_len(), 64 + 2);
1518 assert_eq!(
1519 <WrapperOpaque<[u8; 64]>>::max_encoded_len(),
1520 WrapperOpaque([0u8; 64]).encode().len()
1521 );
1522
1523 assert_eq!(
1524 <WrapperOpaque<[u8; 2usize.pow(14) - 1]>>::max_encoded_len(),
1525 2usize.pow(14) - 1 + 2
1526 );
1527 assert_eq!(<WrapperOpaque<[u8; 2usize.pow(14)]>>::max_encoded_len(), 2usize.pow(14) + 4);
1528
1529 let data = 4u64;
1530 assert!(WrapperOpaque::<u32>::decode(&mut &data.encode().encode()[..]).is_err());
1532 }
1533
1534 #[test]
1535 fn test_keep_opaque_wrapper() {
1536 let data = 3u32.encode().encode();
1537
1538 let keep_opaque = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1539 keep_opaque.try_decode().unwrap();
1540
1541 let data = WrapperOpaque(50u32).encode();
1542 let decoded = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1543 let data = decoded.encode();
1544 WrapperOpaque::<u32>::decode(&mut &data[..]).unwrap();
1545 }
1546
1547 #[test]
1548 fn defensive_min_works() {
1549 assert_eq!(10, 10_u32.defensive_min(11_u32));
1550 assert_eq!(10, 10_u32.defensive_min(10_u32));
1551 }
1552
1553 #[test]
1554 #[cfg(debug_assertions)]
1555 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin\"")]
1556 fn defensive_min_panics() {
1557 10_u32.defensive_min(9_u32);
1558 }
1559
1560 #[test]
1561 fn defensive_strict_min_works() {
1562 assert_eq!(10, 10_u32.defensive_strict_min(11_u32));
1563 assert_eq!(9, 9_u32.defensive_strict_min(10_u32));
1564 }
1565
1566 #[test]
1567 #[cfg(debug_assertions)]
1568 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin strict\"")]
1569 fn defensive_strict_min_panics() {
1570 9_u32.defensive_strict_min(9_u32);
1571 }
1572
1573 #[test]
1574 fn defensive_max_works() {
1575 assert_eq!(11, 11_u32.defensive_max(10_u32));
1576 assert_eq!(10, 10_u32.defensive_max(10_u32));
1577 }
1578
1579 #[test]
1580 #[cfg(debug_assertions)]
1581 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax\"")]
1582 fn defensive_max_panics() {
1583 9_u32.defensive_max(10_u32);
1584 }
1585
1586 #[test]
1587 fn defensive_strict_max_works() {
1588 assert_eq!(11, 11_u32.defensive_strict_max(10_u32));
1589 assert_eq!(10, 10_u32.defensive_strict_max(9_u32));
1590 }
1591
1592 #[test]
1593 #[cfg(debug_assertions)]
1594 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax strict\"")]
1595 fn defensive_strict_max_panics() {
1596 9_u32.defensive_strict_max(9_u32);
1597 }
1598}