pezframe_support/traits/
misc.rs

1// This file is part of Bizinikiwi.
2
3// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Smaller traits used in FRAME which don't need their own file.
19
20use 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
44/// Trait to get the number of variants in any enum.
45pub trait VariantCount {
46	/// Get the number of variants.
47	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
58/// Adapter for `Get<u32>` to access `VARIANT_COUNT` from `trait pub trait VariantCount {`.
59pub 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/// Generic function to mark an execution path as ONLY defensive.
67///
68/// Similar to mark a match arm or `if/else` branch as `unreachable!`.
69#[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/// Trigger a defensive failure if a condition is not met.
101///
102/// Similar to [`assert!`] but will print an error without `debug_assertions` instead of silently
103/// ignoring it. Only accepts one instead of variable formatting arguments.
104///
105/// # Example
106///
107/// ```should_panic
108/// pezframe_support::defensive_assert!(1 == 0, "Must fail")
109/// ```
110#[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
119/// Prelude module for all defensive traits to be imported at once.
120pub mod defensive_prelude {
121	pub use super::{Defensive, DefensiveOption, DefensiveResult};
122}
123
124/// A trait to handle errors and options when you are really sure that a condition must hold, but
125/// not brave enough to `expect` on it, or a default fallback value makes more sense.
126///
127/// This trait mostly focuses on methods that eventually unwrap the inner value. See
128/// [`DefensiveResult`] and [`DefensiveOption`] for methods that specifically apply to the
129/// respective types.
130///
131/// Each function in this trait will have two side effects, aside from behaving exactly as the name
132/// would suggest:
133///
134/// 1. It panics on `#[debug_assertions]`, so if the infallible code is reached in any of the tests,
135///    you realize.
136/// 2. It will log an error using the runtime logging system. This might help you detect such bugs
137///    in production as well. Note that the log message, as of now, are not super expressive. Your
138///    best shot of fully diagnosing the error would be to infer the block number of which the log
139///    message was emitted, then re-execute that block using `check-block` or `try-runtime`
140///    subcommands in bizinikiwi client.
141pub trait Defensive<T> {
142	/// Exactly the same as `unwrap_or`, but it does the defensive warnings explained in the trait
143	/// docs.
144	fn defensive_unwrap_or(self, other: T) -> T;
145
146	/// Exactly the same as `unwrap_or_else`, but it does the defensive warnings explained in the
147	/// trait docs.
148	fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T;
149
150	/// Exactly the same as `unwrap_or_default`, but it does the defensive warnings explained in the
151	/// trait docs.
152	fn defensive_unwrap_or_default(self) -> T
153	where
154		T: Default;
155
156	/// Does not alter the inner value at all, but it will log warnings if the inner value is `None`
157	/// or `Err`.
158	///
159	/// In some ways, this is like  `.defensive_map(|x| x)`.
160	///
161	/// This is useful as:
162	/// ```nocompile
163	/// if let Some(inner) = maybe_value().defensive() {
164	/// 	 	..
165	/// }
166	/// ```
167	fn defensive(self) -> Self;
168
169	/// Same as [`Defensive::defensive`], but it takes a proof as input, and displays it if the
170	/// defensive operation has been triggered.
171	fn defensive_proof(self, proof: &'static str) -> Self;
172}
173
174/// Subset of methods similar to [`Defensive`] that can only work for a `Result`.
175pub trait DefensiveResult<T, E> {
176	/// Defensively map the error into another return type, but you are really sure that this
177	/// conversion should never be needed.
178	fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F>;
179
180	/// Defensively map and unpack the value to something else (`U`), or call the default callback
181	/// if `Err`, which should never happen.
182	fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;
183
184	/// Defensively transform this result into an option, discarding the `Err` variant if it
185	/// happens, which should never happen.
186	fn defensive_ok(self) -> Option<T>;
187
188	/// Exactly the same as `map`, but it prints the appropriate warnings if the value being mapped
189	/// is `Err`.
190	fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E>;
191}
192
193/// Subset of methods similar to [`Defensive`] that can only work for a `Option`.
194pub trait DefensiveOption<T> {
195	/// Potentially map and unpack the value to something else (`U`), or call the default callback
196	/// if `None`, which should never happen.
197	fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;
198
199	/// Defensively transform this option to a result, mapping `None` to the return value of an
200	/// error closure.
201	fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E>;
202
203	/// Defensively transform this option to a result, mapping `None` to a default value.
204	fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E>;
205
206	/// Exactly the same as `map`, but it prints the appropriate warnings if the value being mapped
207	/// is `None`.
208	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
394/// A variant of [`Defensive`] with the same rationale, for the arithmetic operations where in
395/// case an infallible operation fails, it saturates.
396pub trait DefensiveSaturating {
397	/// Return `self` plus `other` defensively.
398	fn defensive_saturating_add(self, other: Self) -> Self;
399	/// Return `self` minus `other` defensively.
400	fn defensive_saturating_sub(self, other: Self) -> Self;
401	/// Return the product of `self` and `other` defensively.
402	fn defensive_saturating_mul(self, other: Self) -> Self;
403	/// Increase `self` by `other` defensively.
404	fn defensive_saturating_accrue(&mut self, other: Self);
405	/// Reduce `self` by `other` defensively.
406	fn defensive_saturating_reduce(&mut self, other: Self);
407	/// Increment `self` by one defensively.
408	fn defensive_saturating_inc(&mut self);
409	/// Decrement `self` by one defensively.
410	fn defensive_saturating_dec(&mut self);
411}
412
413// NOTE: A bit unfortunate, since T has to be bound by all the traits needed. Could make it
414// `DefensiveSaturating<T>` to mitigate.
415impl<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		// Use `replace` here since `take` would require `T: Default`.
427		*self = core::mem::replace(self, One::one()).defensive_saturating_add(other);
428	}
429	fn defensive_saturating_reduce(&mut self, other: Self) {
430		// Use `replace` here since `take` would require `T: Default`.
431		*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
441/// Construct an object by defensively truncating an input if the `TryFrom` conversion fails.
442pub trait DefensiveTruncateFrom<T> {
443	/// Use `TryFrom` first and defensively fall back to truncating otherwise.
444	///
445	/// # Example
446	///
447	/// ```
448	/// use pezframe_support::{BoundedVec, traits::DefensiveTruncateFrom};
449	/// use pezsp_runtime::traits::ConstU32;
450	///
451	/// let unbound = vec![1, 2];
452	/// let bound = BoundedVec::<u8, ConstU32<2>>::defensive_truncate_from(unbound);
453	///
454	/// assert_eq!(bound, vec![1, 2]);
455	/// ```
456	fn defensive_truncate_from(unbound: T) -> Self;
457}
458
459impl<T, U> DefensiveTruncateFrom<U> for T
460where
461	// NOTE: We use the fact that `BoundedVec` and
462	// `BoundedSlice` use `Self` as error type. We could also
463	// require a `Clone` bound and use `unbound.clone()` in the
464	// error case.
465	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
478/// Defensively truncate a value and convert it into its bounded form.
479pub trait DefensiveTruncateInto<T> {
480	/// Defensively truncate a value and convert it into its bounded form.
481	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}
489/// Defensively calculates the minimum of two values.
490///
491/// Can be used in contexts where we assume the receiver value to be (strictly) smaller.
492pub trait DefensiveMin<T> {
493	/// Returns the minimum and defensively checks that `self` is not larger than `other`.
494	///
495	/// # Example
496	///
497	/// ```
498	/// use pezframe_support::traits::DefensiveMin;
499	/// // min(3, 4) is 3.
500	/// assert_eq!(3, 3_u32.defensive_min(4_u32));
501	/// // min(4, 4) is 4.
502	/// assert_eq!(4, 4_u32.defensive_min(4_u32));
503	/// ```
504	///
505	/// ```should_panic
506	/// use pezframe_support::traits::DefensiveMin;
507	/// // min(4, 3) panics.
508	/// 4_u32.defensive_min(3_u32);
509	/// ```
510	fn defensive_min(self, other: T) -> Self;
511
512	/// Returns the minimum and defensively checks that `self` is smaller than `other`.
513	///
514	/// # Example
515	///
516	/// ```
517	/// use pezframe_support::traits::DefensiveMin;
518	/// // min(3, 4) is 3.
519	/// assert_eq!(3, 3_u32.defensive_strict_min(4_u32));
520	/// ```
521	///
522	/// ```should_panic
523	/// use pezframe_support::traits::DefensiveMin;
524	/// // min(4, 4) panics.
525	/// 4_u32.defensive_strict_min(4_u32);
526	/// ```
527	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
553/// Defensively calculates the maximum of two values.
554///
555/// Can be used in contexts where we assume the receiver value to be (strictly) larger.
556pub trait DefensiveMax<T> {
557	/// Returns the maximum and defensively asserts that `other` is not larger than `self`.
558	///
559	/// # Example
560	///
561	/// ```
562	/// use pezframe_support::traits::DefensiveMax;
563	/// // max(4, 3) is 4.
564	/// assert_eq!(4, 4_u32.defensive_max(3_u32));
565	/// // max(4, 4) is 4.
566	/// assert_eq!(4, 4_u32.defensive_max(4_u32));
567	/// ```
568	///
569	/// ```should_panic
570	/// use pezframe_support::traits::DefensiveMax;
571	/// // max(4, 5) panics.
572	/// 4_u32.defensive_max(5_u32);
573	/// ```
574	fn defensive_max(self, other: T) -> Self;
575
576	/// Returns the maximum and defensively asserts that `other` is smaller than `self`.
577	///
578	/// # Example
579	///
580	/// ```
581	/// use pezframe_support::traits::DefensiveMax;
582	/// // y(4, 3) is 4.
583	/// assert_eq!(4, 4_u32.defensive_strict_max(3_u32));
584	/// ```
585	///
586	/// ```should_panic
587	/// use pezframe_support::traits::DefensiveMax;
588	/// // max(4, 4) panics.
589	/// 4_u32.defensive_strict_max(4_u32);
590	/// ```
591	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
617/// Anything that can have a `::len()` method.
618pub trait Len {
619	/// Return the length of data type.
620	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
632/// A type for which some values make sense to be able to drop without further consideration.
633pub trait TryDrop: Sized {
634	/// Drop an instance cleanly. Only works if its value represents "no-operation".
635	fn try_drop(self) -> Result<(), Self>;
636}
637
638impl TryDrop for () {
639	fn try_drop(self) -> Result<(), Self> {
640		Ok(())
641	}
642}
643
644/// Return type used when we need to return one of two items, each of the opposite direction or
645/// sign, with one (`Same`) being of the same type as the `self` or primary argument of the function
646/// that returned it.
647pub enum SameOrOther<A, B> {
648	/// No item.
649	None,
650	/// An item of the same type as the `Self` on which the return function was called.
651	Same(A),
652	/// An item of the opposite type to the `Self` on which the return function was called.
653	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	/// Returns `Ok` with the inner value of `Same` if `self` is that, otherwise returns `Err` with
668	/// `self`.
669	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	/// Returns `Ok` with the inner value of `Other` if `self` is that, otherwise returns `Err` with
677	/// `self`.
678	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	/// Returns `Ok` if `self` is `None`, otherwise returns `Err` with `self`.
686	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/// Handler for when a new account has been created.
717#[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	/// A new account `who` has been registered.
722	fn on_new_account(who: &AccountId);
723}
724
725/// The account with the given id was reaped.
726#[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	/// The account with the given id was reaped.
731	fn on_killed_account(who: &AccountId);
732}
733
734/// A simple, generic one-parameter event notifier/handler.
735pub trait HandleLifetime<T> {
736	/// An account was created.
737	fn created(_t: &T) -> Result<(), DispatchError> {
738		Ok(())
739	}
740
741	/// An account was killed.
742	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
755/// Trait to deal with unix time.
756pub trait UnixTime {
757	/// Return duration since `SystemTime::UNIX_EPOCH`.
758	fn now() -> core::time::Duration;
759}
760
761/// Trait to be used when types are exactly same.
762///
763/// This allow to convert back and forth from type, a reference and a mutable reference.
764pub trait IsType<T>: Into<T> + From<T> {
765	/// Cast reference.
766	fn from_ref(t: &T) -> &Self;
767
768	/// Cast reference.
769	fn into_ref(&self) -> &T;
770
771	/// Cast mutable reference.
772	fn from_mut(t: &mut T) -> &mut Self;
773
774	/// Cast mutable reference.
775	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
793/// Something that can be checked to be a of sub type `T`.
794///
795/// This is useful for enums where each variant encapsulates a different sub type, and
796/// you need access to these sub types.
797///
798/// For example, in FRAME, this trait is implemented for the runtime `Call` enum. Pallets use this
799/// to check if a certain call is an instance of the local pezpallet's `Call` enum.
800///
801/// # Example
802///
803/// ```
804/// # use pezframe_support::traits::IsSubType;
805///
806/// enum Test {
807///     String(String),
808///     U32(u32),
809/// }
810///
811/// impl IsSubType<String> for Test {
812///     fn is_sub_type(&self) -> Option<&String> {
813///         match self {
814///             Self::String(ref r) => Some(r),
815///             _ => None,
816///         }
817///     }
818/// }
819///
820/// impl IsSubType<u32> for Test {
821///     fn is_sub_type(&self) -> Option<&u32> {
822///         match self {
823///             Self::U32(ref r) => Some(r),
824///             _ => None,
825///         }
826///     }
827/// }
828///
829/// fn main() {
830///     let data = Test::String("test".into());
831///
832///     assert_eq!("test", IsSubType::<String>::is_sub_type(&data).unwrap().as_str());
833/// }
834/// ```
835pub trait IsSubType<T> {
836	/// Returns `Some(_)` if `self` is an instance of sub type `T`.
837	fn is_sub_type(&self) -> Option<&T>;
838}
839
840/// Something that can execute a given block.
841///
842/// Executing a block means that all extrinsics in a given block will be executed and the resulting
843/// header will be checked against the header of the given block.
844pub trait ExecuteBlock<Block: BlockT> {
845	/// Execute the given `block`.
846	///
847	/// This will execute all extrinsics in the block and check that the resulting header is
848	/// correct.
849	///
850	/// This function is a wrapper around [`Self::verify_and_remove_seal`] and
851	/// [`Self::execute_verified_block`].
852	///
853	/// # Panic
854	///
855	/// Panics when an extrinsics panics or the resulting header doesn't match the expected header
856	/// or the seal is invalid.
857	fn execute_block(mut block: Block::LazyBlock) {
858		Self::verify_and_remove_seal(&mut block);
859		Self::execute_verified_block(block);
860	}
861
862	/// Verify and remove seal.
863	///
864	/// Verifies any seal meant for the consensus logic represented by the implementation. An
865	/// implementation may also chooses to not verify anything.
866	///
867	/// # Panic
868	///
869	/// Panics if a seal is invalid or if a seal is required, but not present.
870	fn verify_and_remove_seal(block: &mut Block::LazyBlock);
871
872	/// Executes the given `block` after it was verified by `[Self::verify_and_remove_seal]`.
873	///
874	/// # Panic
875	///
876	/// Panics when an extrinsics panics or the resulting header doesn't match the expected header.
877	fn execute_verified_block(block: Block::LazyBlock);
878}
879
880/// Something that can compare privileges of two origins.
881pub trait PrivilegeCmp<Origin> {
882	/// Compare the `left` to the `right` origin.
883	///
884	/// The returned ordering should be from the pov of the `left` origin.
885	///
886	/// Should return `None` when it can not compare the given origins.
887	fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering>;
888}
889
890/// Implementation of [`PrivilegeCmp`] that only checks for equal origins.
891///
892/// This means it will either return [`Ordering::Equal`] or `None`.
893pub 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/// Off-chain computation trait.
901///
902/// Implementing this trait on a module allows you to perform long-running tasks
903/// that make (by default) validators generate transactions that feed results
904/// of those long-running computations back on chain.
905///
906/// NOTE: This function runs off-chain, so it can access the block state,
907/// but cannot preform any alterations. More specifically alterations are
908/// not forbidden, but they are not persisted in any way after the worker
909/// has finished.
910#[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	/// This function is being called after every block import (when fully synced).
915	///
916	/// Implement this and use any of the `Offchain` `pezsp_io` set of APIs
917	/// to perform off-chain computations, calls and submit transactions
918	/// with results to trigger any on-chain changes.
919	/// Any state alterations are lost and are not persisted.
920	fn offchain_worker(_n: BlockNumber) {}
921}
922
923/// Some amount of backing from a group. The precise definition of what it means to "back" something
924/// is left flexible.
925pub struct Backing {
926	/// The number of members of the group that back some motion.
927	pub approvals: u32,
928	/// The total count of group members.
929	pub eligible: u32,
930}
931
932/// Retrieve the backing from an object's ref.
933pub trait GetBacking {
934	/// Returns `Some` `Backing` if `self` represents a fractional/groupwise backing of some
935	/// implicit motion. `None` if it does not.
936	fn get_backing(&self) -> Option<Backing>;
937}
938
939/// A trait to check if an extrinsic is an inherent.
940pub trait IsInherent<Extrinsic> {
941	/// Whether this extrinsic is an inherent.
942	fn is_inherent(ext: &Extrinsic) -> bool;
943}
944
945/// Interface for types capable of constructing an inherent extrinsic.
946pub trait InherentBuilder: ExtrinsicCall {
947	/// Create a new inherent from a given call.
948	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
964/// Interface for types capable of constructing a signed transaction.
965pub trait SignedTransactionBuilder: ExtrinsicCall {
966	type Address;
967	type Signature;
968	type Extension;
969
970	/// Create a new signed transaction from a given call and extension using the provided signature
971	/// data.
972	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
1002/// Something that can estimate the fee of a (frame-based) call.
1003///
1004/// Typically, the same pezpallet that will charge transaction fees will implement this.
1005pub trait EstimateCallFee<Call, Balance> {
1006	/// Estimate the fee of this call.
1007	///
1008	/// The dispatch info and the length is deduced from the call. The post info can optionally be
1009	/// provided.
1010	fn estimate_call_fee(call: &Call, post_info: crate::dispatch::PostDispatchInfo) -> Balance;
1011}
1012
1013// Useful for building mocks.
1014#[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/// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec<u8>`.
1029///
1030/// The encoding is the encoding of `T` prepended with the compact encoding of its size in bytes.
1031/// Thus the encoded value can be decoded as a `Vec<u8>`.
1032#[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		// See scale encoding: https://docs.pezkuwichain.io/reference/scale-codec/
1081		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/// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec<u8>`.
1108///
1109/// This type is similar to [`WrapperOpaque`], but it differs in the way it stores the type `T`.
1110/// While [`WrapperOpaque`] stores the decoded type, the [`WrapperKeepOpaque`] stores the type only
1111/// in its opaque format, aka as a `Vec<u8>`. To access the real type `T` [`Self::try_decode`] needs
1112/// to be used.
1113#[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	/// Try to decode the wrapped type from the inner `data`.
1121	///
1122	/// Returns `None` if the decoding failed.
1123	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	/// Returns the length of the encoded `T`.
1128	pub fn encoded_len(&self) -> usize {
1129		self.data.len()
1130	}
1131
1132	/// Returns the encoded data.
1133	pub fn encoded(&self) -> &[u8] {
1134		&self.data
1135	}
1136
1137	/// Create from the given encoded `data`.
1138	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
1194/// A interface for looking up preimages from their hash on chain.
1195pub trait PreimageProvider<Hash> {
1196	/// Returns whether a preimage exists for a given hash.
1197	///
1198	/// A value of `true` implies that `get_preimage` is `Some`.
1199	fn have_preimage(hash: &Hash) -> bool;
1200
1201	/// Returns the preimage for a given hash.
1202	fn get_preimage(hash: &Hash) -> Option<Vec<u8>>;
1203
1204	/// Returns whether a preimage request exists for a given hash.
1205	fn preimage_requested(hash: &Hash) -> bool;
1206
1207	/// Request that someone report a preimage. Providers use this to optimise the economics for
1208	/// preimage reporting.
1209	fn request_preimage(hash: &Hash);
1210
1211	/// Cancel a previous preimage request.
1212	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
1229/// A interface for managing preimages to hashes on chain.
1230///
1231/// Note that this API does not assume any underlying user is calling, and thus
1232/// does not handle any preimage ownership or fees. Other system level logic that
1233/// uses this API should implement that on their own side.
1234pub trait PreimageRecipient<Hash>: PreimageProvider<Hash> {
1235	/// Maximum size of a preimage.
1236	type MaxSize: Get<u32>;
1237
1238	/// Store the bytes of a preimage on chain infallible due to the bounded type.
1239	fn note_preimage(bytes: crate::BoundedVec<u8, Self::MaxSize>);
1240
1241	/// Clear a previously noted preimage. This is infallible and should be treated more like a
1242	/// hint - if it was not previously noted or if it is now requested, then this will not do
1243	/// anything.
1244	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
1253/// Trait for touching/creating an asset account with a deposit taken from a designated depositor
1254/// specified by the client.
1255///
1256/// Ensures that transfers to the touched account will succeed without being denied by the account
1257/// creation requirements. For example, it is useful for the account creation of non-sufficient
1258/// assets when its system account may not have the free consumer reference required for it. If
1259/// there is no risk of failing to meet those requirements, the touch operation can be a no-op, as
1260/// is common for native assets.
1261pub trait AccountTouch<AssetId, AccountId> {
1262	/// The type for currency units of the deposit.
1263	type Balance;
1264
1265	/// The deposit amount of a native currency required for touching an account of the `asset`.
1266	fn deposit_required(asset: AssetId) -> Self::Balance;
1267
1268	/// Check if an account for a given asset should be touched to meet the existence requirements.
1269	fn should_touch(asset: AssetId, who: &AccountId) -> bool;
1270
1271	/// Create an account for `who` of the `asset` with a deposit taken from the `depositor`.
1272	fn touch(asset: AssetId, who: &AccountId, depositor: &AccountId) -> DispatchResult;
1273}
1274
1275/// Trait for reporting additional validator reward points
1276pub trait RewardsReporter<ValidatorId> {
1277	/// The input is an iterator of tuples of validator account IDs and the amount of points they
1278	/// should be rewarded.
1279	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); // defensive failure
1327	}
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); // defensive failure
1347	}
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(); // defensive failure
1370	}
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(); // defensive failure
1393	}
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		// Ensure that we check that the `Vec<u8>` is consumed completely on decode.
1498		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}