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