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
1015#[cfg(feature = "std")]
1017impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
1018 fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
1019 T.into()
1020 }
1021}
1022
1023#[cfg(feature = "std")]
1024impl<Call, Balance: From<u32>, const T: u64> EstimateCallFee<Call, Balance> for ConstU64<T> {
1025 fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
1026 (T as u32).into()
1027 }
1028}
1029
1030#[derive(Debug, Eq, PartialEq, Default, Clone)]
1035#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
1036pub struct WrapperOpaque<T>(pub T);
1037
1038impl<T: Encode> EncodeLike for WrapperOpaque<T> {}
1039impl<T: Encode> EncodeLike<WrapperKeepOpaque<T>> for WrapperOpaque<T> {}
1040
1041impl<T: Encode> Encode for WrapperOpaque<T> {
1042 fn size_hint(&self) -> usize {
1043 self.0.size_hint().saturating_add(<codec::Compact<u32>>::max_encoded_len())
1044 }
1045
1046 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1047 self.0.encode().encode_to(dest);
1048 }
1049
1050 fn encode(&self) -> Vec<u8> {
1051 self.0.encode().encode()
1052 }
1053
1054 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1055 self.0.encode().using_encoded(f)
1056 }
1057}
1058
1059impl<T: Decode> Decode for WrapperOpaque<T> {
1060 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1061 Ok(Self(T::decode_all_with_depth_limit(
1062 crate::MAX_EXTRINSIC_DEPTH,
1063 &mut &<Vec<u8>>::decode(input)?[..],
1064 )?))
1065 }
1066
1067 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1068 <Vec<u8>>::skip(input)
1069 }
1070}
1071
1072impl<T> From<T> for WrapperOpaque<T> {
1073 fn from(t: T) -> Self {
1074 Self(t)
1075 }
1076}
1077
1078impl<T: MaxEncodedLen> MaxEncodedLen for WrapperOpaque<T> {
1079 fn max_encoded_len() -> usize {
1080 let t_max_len = T::max_encoded_len();
1081
1082 if t_max_len < 64 {
1084 t_max_len + 1
1085 } else if t_max_len < 2usize.pow(14) {
1086 t_max_len + 2
1087 } else if t_max_len < 2usize.pow(30) {
1088 t_max_len + 4
1089 } else {
1090 <codec::Compact<u32>>::max_encoded_len().saturating_add(T::max_encoded_len())
1091 }
1092 }
1093}
1094
1095impl<T: TypeInfo + 'static> TypeInfo for WrapperOpaque<T> {
1096 type Identity = Self;
1097 fn type_info() -> Type {
1098 Type::builder()
1099 .path(Path::new("WrapperOpaque", module_path!()))
1100 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1101 .composite(
1102 Fields::unnamed()
1103 .field(|f| f.compact::<u32>())
1104 .field(|f| f.ty::<T>().type_name("T")),
1105 )
1106 }
1107}
1108
1109#[derive(Debug, Eq, PartialEq, Default, Clone)]
1116pub struct WrapperKeepOpaque<T> {
1117 data: Vec<u8>,
1118 _phantom: core::marker::PhantomData<T>,
1119}
1120
1121impl<T: Decode> WrapperKeepOpaque<T> {
1122 pub fn try_decode(&self) -> Option<T> {
1126 T::decode_all_with_depth_limit(crate::MAX_EXTRINSIC_DEPTH, &mut &self.data[..]).ok()
1127 }
1128
1129 pub fn encoded_len(&self) -> usize {
1131 self.data.len()
1132 }
1133
1134 pub fn encoded(&self) -> &[u8] {
1136 &self.data
1137 }
1138
1139 pub fn from_encoded(data: Vec<u8>) -> Self {
1141 Self { data, _phantom: core::marker::PhantomData }
1142 }
1143}
1144
1145impl<T: Encode> EncodeLike for WrapperKeepOpaque<T> {}
1146impl<T: Encode> EncodeLike<WrapperOpaque<T>> for WrapperKeepOpaque<T> {}
1147
1148impl<T: Encode> Encode for WrapperKeepOpaque<T> {
1149 fn size_hint(&self) -> usize {
1150 self.data.len() + codec::Compact::<u32>::compact_len(&(self.data.len() as u32))
1151 }
1152
1153 fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
1154 self.data.encode_to(dest);
1155 }
1156
1157 fn encode(&self) -> Vec<u8> {
1158 self.data.encode()
1159 }
1160
1161 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1162 self.data.using_encoded(f)
1163 }
1164}
1165
1166impl<T: Decode> Decode for WrapperKeepOpaque<T> {
1167 fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
1168 Ok(Self { data: Vec::<u8>::decode(input)?, _phantom: core::marker::PhantomData })
1169 }
1170
1171 fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
1172 <Vec<u8>>::skip(input)
1173 }
1174}
1175
1176impl<T: MaxEncodedLen> MaxEncodedLen for WrapperKeepOpaque<T> {
1177 fn max_encoded_len() -> usize {
1178 WrapperOpaque::<T>::max_encoded_len()
1179 }
1180}
1181
1182impl<T: TypeInfo + 'static> TypeInfo for WrapperKeepOpaque<T> {
1183 type Identity = Self;
1184 fn type_info() -> Type {
1185 Type::builder()
1186 .path(Path::new("WrapperKeepOpaque", module_path!()))
1187 .type_params(vec![TypeParameter::new("T", Some(meta_type::<T>()))])
1188 .composite(
1189 Fields::unnamed()
1190 .field(|f| f.compact::<u32>())
1191 .field(|f| f.ty::<T>().type_name("T")),
1192 )
1193 }
1194}
1195
1196pub trait PreimageProvider<Hash> {
1198 fn have_preimage(hash: &Hash) -> bool;
1202
1203 fn get_preimage(hash: &Hash) -> Option<Vec<u8>>;
1205
1206 fn preimage_requested(hash: &Hash) -> bool;
1208
1209 fn request_preimage(hash: &Hash);
1212
1213 fn unrequest_preimage(hash: &Hash);
1215}
1216
1217impl<Hash> PreimageProvider<Hash> for () {
1218 fn have_preimage(_: &Hash) -> bool {
1219 false
1220 }
1221 fn get_preimage(_: &Hash) -> Option<Vec<u8>> {
1222 None
1223 }
1224 fn preimage_requested(_: &Hash) -> bool {
1225 false
1226 }
1227 fn request_preimage(_: &Hash) {}
1228 fn unrequest_preimage(_: &Hash) {}
1229}
1230
1231pub trait PreimageRecipient<Hash>: PreimageProvider<Hash> {
1237 type MaxSize: Get<u32>;
1239
1240 fn note_preimage(bytes: crate::BoundedVec<u8, Self::MaxSize>);
1242
1243 fn unnote_preimage(hash: &Hash);
1247}
1248
1249impl<Hash> PreimageRecipient<Hash> for () {
1250 type MaxSize = ();
1251 fn note_preimage(_: crate::BoundedVec<u8, Self::MaxSize>) {}
1252 fn unnote_preimage(_: &Hash) {}
1253}
1254
1255pub trait AccountTouch<AssetId, AccountId> {
1264 type Balance;
1266
1267 fn deposit_required(asset: AssetId) -> Self::Balance;
1269
1270 fn should_touch(asset: AssetId, who: &AccountId) -> bool;
1272
1273 fn touch(asset: AssetId, who: &AccountId, depositor: &AccountId) -> DispatchResult;
1275}
1276
1277pub trait RewardsReporter<ValidatorId> {
1279 fn reward_by_ids(validators_points: impl IntoIterator<Item = (ValidatorId, u32)>);
1282}
1283
1284#[cfg(test)]
1285mod test {
1286 use super::*;
1287 use core::marker::PhantomData;
1288 use sp_core::bounded::{BoundedSlice, BoundedVec};
1289
1290 #[test]
1291 fn defensive_assert_works() {
1292 defensive_assert!(true);
1293 defensive_assert!(true,);
1294 defensive_assert!(true, "must work");
1295 defensive_assert!(true, "must work",);
1296 }
1297
1298 #[test]
1299 #[cfg(debug_assertions)]
1300 #[should_panic(expected = "Defensive failure has been triggered!: \"1 == 0\": \"Must fail\"")]
1301 fn defensive_assert_panics() {
1302 defensive_assert!(1 == 0, "Must fail");
1303 }
1304
1305 #[test]
1306 #[cfg(not(debug_assertions))]
1307 fn defensive_assert_does_not_panic() {
1308 defensive_assert!(1 == 0, "Must fail");
1309 }
1310
1311 #[test]
1312 #[cfg(not(debug_assertions))]
1313 fn defensive_saturating_accrue_works() {
1314 let mut v = 1_u32;
1315 v.defensive_saturating_accrue(2);
1316 assert_eq!(v, 3);
1317 v.defensive_saturating_accrue(u32::MAX);
1318 assert_eq!(v, u32::MAX);
1319 v.defensive_saturating_accrue(1);
1320 assert_eq!(v, u32::MAX);
1321 }
1322
1323 #[test]
1324 #[cfg(debug_assertions)]
1325 #[should_panic(expected = "Defensive")]
1326 fn defensive_saturating_accrue_panics() {
1327 let mut v = u32::MAX;
1328 v.defensive_saturating_accrue(1); }
1330
1331 #[test]
1332 #[cfg(not(debug_assertions))]
1333 fn defensive_saturating_reduce_works() {
1334 let mut v = u32::MAX;
1335 v.defensive_saturating_reduce(3);
1336 assert_eq!(v, u32::MAX - 3);
1337 v.defensive_saturating_reduce(u32::MAX);
1338 assert_eq!(v, 0);
1339 v.defensive_saturating_reduce(1);
1340 assert_eq!(v, 0);
1341 }
1342
1343 #[test]
1344 #[cfg(debug_assertions)]
1345 #[should_panic(expected = "Defensive")]
1346 fn defensive_saturating_reduce_panics() {
1347 let mut v = 0_u32;
1348 v.defensive_saturating_reduce(1); }
1350
1351 #[test]
1352 #[cfg(not(debug_assertions))]
1353 fn defensive_saturating_inc_works() {
1354 let mut v = 0_u32;
1355 for i in 1..10 {
1356 v.defensive_saturating_inc();
1357 assert_eq!(v, i);
1358 }
1359 v += u32::MAX - 10;
1360 v.defensive_saturating_inc();
1361 assert_eq!(v, u32::MAX);
1362 v.defensive_saturating_inc();
1363 assert_eq!(v, u32::MAX);
1364 }
1365
1366 #[test]
1367 #[cfg(debug_assertions)]
1368 #[should_panic(expected = "Defensive")]
1369 fn defensive_saturating_inc_panics() {
1370 let mut v = u32::MAX;
1371 v.defensive_saturating_inc(); }
1373
1374 #[test]
1375 #[cfg(not(debug_assertions))]
1376 fn defensive_saturating_dec_works() {
1377 let mut v = u32::MAX;
1378 for i in 1..10 {
1379 v.defensive_saturating_dec();
1380 assert_eq!(v, u32::MAX - i);
1381 }
1382 v -= u32::MAX - 10;
1383 v.defensive_saturating_dec();
1384 assert_eq!(v, 0);
1385 v.defensive_saturating_dec();
1386 assert_eq!(v, 0);
1387 }
1388
1389 #[test]
1390 #[cfg(debug_assertions)]
1391 #[should_panic(expected = "Defensive")]
1392 fn defensive_saturating_dec_panics() {
1393 let mut v = 0_u32;
1394 v.defensive_saturating_dec(); }
1396
1397 #[test]
1398 #[cfg(not(debug_assertions))]
1399 fn defensive_truncating_from_vec_defensive_works() {
1400 let unbound = vec![1u32, 2];
1401 let bound = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1402 assert_eq!(bound, vec![1u32]);
1403 }
1404
1405 #[test]
1406 #[cfg(not(debug_assertions))]
1407 fn defensive_truncating_from_slice_defensive_works() {
1408 let unbound = &[1u32, 2];
1409 let bound = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1410 assert_eq!(bound, &[1u32][..]);
1411 }
1412
1413 #[test]
1414 #[cfg(debug_assertions)]
1415 #[should_panic(
1416 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1417 )]
1418 fn defensive_truncating_from_vec_defensive_panics() {
1419 let unbound = vec![1u32, 2];
1420 let _ = BoundedVec::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1421 }
1422
1423 #[test]
1424 #[cfg(debug_assertions)]
1425 #[should_panic(
1426 expected = "Defensive failure has been triggered!: \"DefensiveTruncateFrom truncating\""
1427 )]
1428 fn defensive_truncating_from_slice_defensive_panics() {
1429 let unbound = &[1u32, 2];
1430 let _ = BoundedSlice::<u32, ConstU32<1>>::defensive_truncate_from(unbound);
1431 }
1432
1433 #[test]
1434 fn defensive_truncate_from_vec_works() {
1435 let unbound = vec![1u32, 2, 3];
1436 let bound = BoundedVec::<u32, ConstU32<3>>::defensive_truncate_from(unbound.clone());
1437 assert_eq!(bound, unbound);
1438 }
1439
1440 #[test]
1441 fn defensive_truncate_from_slice_works() {
1442 let unbound = [1u32, 2, 3];
1443 let bound = BoundedSlice::<u32, ConstU32<3>>::defensive_truncate_from(&unbound);
1444 assert_eq!(bound, &unbound[..]);
1445 }
1446
1447 #[derive(Encode, Decode)]
1448 enum NestedType {
1449 Nested(Box<Self>),
1450 Done,
1451 }
1452
1453 #[test]
1454 fn test_opaque_wrapper_decode_limit() {
1455 let limit = crate::MAX_EXTRINSIC_DEPTH as usize;
1456 let mut ok_bytes = vec![0u8; limit];
1457 ok_bytes.push(1u8);
1458 let mut err_bytes = vec![0u8; limit + 1];
1459 err_bytes.push(1u8);
1460 assert!(<WrapperOpaque<NestedType>>::decode(&mut &ok_bytes.encode()[..]).is_ok());
1461 assert!(<WrapperOpaque<NestedType>>::decode(&mut &err_bytes.encode()[..]).is_err());
1462
1463 let ok_keep_opaque = WrapperKeepOpaque { data: ok_bytes, _phantom: PhantomData };
1464 let err_keep_opaque = WrapperKeepOpaque { data: err_bytes, _phantom: PhantomData };
1465
1466 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&ok_keep_opaque).is_some());
1467 assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&err_keep_opaque).is_none());
1468 }
1469
1470 #[test]
1471 fn test_opaque_wrapper() {
1472 let encoded = WrapperOpaque(3u32).encode();
1473 assert_eq!(encoded, [codec::Compact(4u32).encode(), 3u32.to_le_bytes().to_vec()].concat());
1474 let vec_u8 = <Vec<u8>>::decode(&mut &encoded[..]).unwrap();
1475 let decoded_from_vec_u8 = u32::decode(&mut &vec_u8[..]).unwrap();
1476 assert_eq!(decoded_from_vec_u8, 3u32);
1477 let decoded = <WrapperOpaque<u32>>::decode(&mut &encoded[..]).unwrap();
1478 assert_eq!(decoded.0, 3u32);
1479
1480 assert_eq!(<WrapperOpaque<[u8; 63]>>::max_encoded_len(), 63 + 1);
1481 assert_eq!(
1482 <WrapperOpaque<[u8; 63]>>::max_encoded_len(),
1483 WrapperOpaque([0u8; 63]).encode().len()
1484 );
1485
1486 assert_eq!(<WrapperOpaque<[u8; 64]>>::max_encoded_len(), 64 + 2);
1487 assert_eq!(
1488 <WrapperOpaque<[u8; 64]>>::max_encoded_len(),
1489 WrapperOpaque([0u8; 64]).encode().len()
1490 );
1491
1492 assert_eq!(
1493 <WrapperOpaque<[u8; 2usize.pow(14) - 1]>>::max_encoded_len(),
1494 2usize.pow(14) - 1 + 2
1495 );
1496 assert_eq!(<WrapperOpaque<[u8; 2usize.pow(14)]>>::max_encoded_len(), 2usize.pow(14) + 4);
1497
1498 let data = 4u64;
1499 assert!(WrapperOpaque::<u32>::decode(&mut &data.encode().encode()[..]).is_err());
1501 }
1502
1503 #[test]
1504 fn test_keep_opaque_wrapper() {
1505 let data = 3u32.encode().encode();
1506
1507 let keep_opaque = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1508 keep_opaque.try_decode().unwrap();
1509
1510 let data = WrapperOpaque(50u32).encode();
1511 let decoded = WrapperKeepOpaque::<u32>::decode(&mut &data[..]).unwrap();
1512 let data = decoded.encode();
1513 WrapperOpaque::<u32>::decode(&mut &data[..]).unwrap();
1514 }
1515
1516 #[test]
1517 fn defensive_min_works() {
1518 assert_eq!(10, 10_u32.defensive_min(11_u32));
1519 assert_eq!(10, 10_u32.defensive_min(10_u32));
1520 }
1521
1522 #[test]
1523 #[cfg(debug_assertions)]
1524 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin\"")]
1525 fn defensive_min_panics() {
1526 10_u32.defensive_min(9_u32);
1527 }
1528
1529 #[test]
1530 fn defensive_strict_min_works() {
1531 assert_eq!(10, 10_u32.defensive_strict_min(11_u32));
1532 assert_eq!(9, 9_u32.defensive_strict_min(10_u32));
1533 }
1534
1535 #[test]
1536 #[cfg(debug_assertions)]
1537 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin strict\"")]
1538 fn defensive_strict_min_panics() {
1539 9_u32.defensive_strict_min(9_u32);
1540 }
1541
1542 #[test]
1543 fn defensive_max_works() {
1544 assert_eq!(11, 11_u32.defensive_max(10_u32));
1545 assert_eq!(10, 10_u32.defensive_max(10_u32));
1546 }
1547
1548 #[test]
1549 #[cfg(debug_assertions)]
1550 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax\"")]
1551 fn defensive_max_panics() {
1552 9_u32.defensive_max(10_u32);
1553 }
1554
1555 #[test]
1556 fn defensive_strict_max_works() {
1557 assert_eq!(11, 11_u32.defensive_strict_max(10_u32));
1558 assert_eq!(10, 10_u32.defensive_strict_max(9_u32));
1559 }
1560
1561 #[test]
1562 #[cfg(debug_assertions)]
1563 #[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax strict\"")]
1564 fn defensive_strict_max_panics() {
1565 9_u32.defensive_strict_max(9_u32);
1566 }
1567}