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