Minor improvements to bounded_vec and defensive. (#10873)

* Fix a few things in bounded_vec

* add test for try_extend

* Update frame/support/src/storage/bounded_vec.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* some review comments

* use swap

* remove clone

* use pop instead of truncate

* remove warn

* review comments

* Update frame/support/src/storage/bounded_vec.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* fix rustdoc

* fix links

* undo link

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Kian Paimani
2022-02-26 08:39:56 +00:00
committed by GitHub
parent 4c984500a7
commit b77d3f917d
5 changed files with 189 additions and 171 deletions
+1 -1
View File
@@ -866,7 +866,7 @@ impl<T: Config> Pallet<T> {
let new_pos = queue.binary_search_by_key(&ayes, |x| x.1).unwrap_or_else(|x| x);
branch = if maybe_old_pos.is_none() && new_pos > 0 {
// Just insert.
queue.force_insert_keep_right(new_pos, (index, ayes));
let _ = queue.force_insert_keep_right(new_pos, (index, ayes));
ServiceBranch::RequeuedInsertion
} else if let Some(old_pos) = maybe_old_pos {
// We were in the queue - slide into the correct position.
+1 -1
View File
@@ -86,7 +86,7 @@ impl<T: Ord, S: Get<u32>> InsertSorted<T> for BoundedVec<T, S> {
mut f: F,
) -> bool {
let index = self.binary_search_by_key::<K, F>(&f(&t), f).unwrap_or_else(|x| x);
self.force_insert_keep_right(index, t)
self.force_insert_keep_right(index, t).is_ok()
}
}
@@ -119,7 +119,17 @@ impl<T, S> BoundedVec<T, S> {
self.0
}
/// Exactly the same semantics as [`Vec::remove`].
/// Exactly the same semantics as [`slice::sort_by`].
///
/// This is safe since sorting cannot change the number of elements in the vector.
pub fn sort_by<F>(&mut self, compare: F)
where
F: FnMut(&T, &T) -> sp_std::cmp::Ordering,
{
self.0.sort_by(compare)
}
/// Exactly the same semantics as `Vec::remove`.
///
/// # Panics
///
@@ -128,7 +138,7 @@ impl<T, S> BoundedVec<T, S> {
self.0.remove(index)
}
/// Exactly the same semantics as [`Vec::swap_remove`].
/// Exactly the same semantics as `slice::swap_remove`.
///
/// # Panics
///
@@ -137,12 +147,12 @@ impl<T, S> BoundedVec<T, S> {
self.0.swap_remove(index)
}
/// Exactly the same semantics as [`Vec::retain`].
/// Exactly the same semantics as `Vec::retain`.
pub fn retain<F: FnMut(&T) -> bool>(&mut self, f: F) {
self.0.retain(f)
}
/// Exactly the same semantics as [`slice::get_mut`].
/// Exactly the same semantics as `slice::get_mut`.
pub fn get_mut<I: SliceIndex<[T]>>(
&mut self,
index: I,
@@ -150,12 +160,16 @@ impl<T, S> BoundedVec<T, S> {
self.0.get_mut(index)
}
/// Exactly the same semantics as [`Vec::truncate`].
/// Exactly the same semantics as `Vec::truncate`.
///
/// This is safe because `truncate` can never increase the length of the internal vector.
pub fn truncate(&mut self, s: usize) {
self.0.truncate(s);
}
/// Exactly the same semantics as [`Vec::pop`].
/// Exactly the same semantics as `Vec::pop`.
///
/// This is safe since popping can only shrink the inner vector.
pub fn pop(&mut self) -> Option<T> {
self.0.pop()
}
@@ -191,54 +205,76 @@ impl<T, S: Get<u32>> BoundedVec<T, S> {
S::get() as usize
}
/// Forces the insertion of `s` into `self` retaining all items with index at least `index`.
/// Returns true of this collection is full.
pub fn is_full(&self) -> bool {
self.len() >= Self::bound()
}
/// Forces the insertion of `element` into `self` retaining all items with index at least
/// `index`.
///
/// If `index == 0` and `self.len() == Self::bound()`, then this is a no-op.
///
/// If `Self::bound() < index` or `self.len() < index`, then this is also a no-op.
///
/// Returns `true` if the item was inserted.
pub fn force_insert_keep_right(&mut self, index: usize, element: T) -> bool {
/// Returns `Ok(maybe_removed)` if the item was inserted, where `maybe_removed` is
/// `Some(removed)` if an item was removed to make room for the new one. Returns `Err(())` if
/// `element` cannot be inserted.
pub fn force_insert_keep_right(
&mut self,
index: usize,
mut element: T,
) -> Result<Option<T>, ()> {
// Check against panics.
if Self::bound() < index || self.len() < index {
return false
}
if self.len() < Self::bound() {
Err(())
} else if self.len() < Self::bound() {
// Cannot panic since self.len() >= index;
self.0.insert(index, element);
Ok(None)
} else {
if index == 0 {
return false
return Err(())
}
self[0] = element;
sp_std::mem::swap(&mut self[0], &mut element);
// `[0..index] cannot panic since self.len() >= index.
// `rotate_left(1)` cannot panic because there is at least 1 element.
self[0..index].rotate_left(1);
Ok(Some(element))
}
true
}
/// Forces the insertion of `s` into `self` retaining all items with index at most `index`.
/// Forces the insertion of `element` into `self` retaining all items with index at most
/// `index`.
///
/// If `index == Self::bound()` and `self.len() == Self::bound()`, then this is a no-op.
///
/// If `Self::bound() < index` or `self.len() < index`, then this is also a no-op.
///
/// Returns `true` if the item was inserted.
pub fn force_insert_keep_left(&mut self, index: usize, element: T) -> bool {
/// Returns `Ok(maybe_removed)` if the item was inserted, where `maybe_removed` is
/// `Some(removed)` if an item was removed to make room for the new one. Returns `Err(())` if
/// `element` cannot be inserted.
pub fn force_insert_keep_left(&mut self, index: usize, element: T) -> Result<Option<T>, ()> {
// Check against panics.
if Self::bound() < index || self.len() < index || Self::bound() == 0 {
return false
return Err(())
}
// Noop condition.
if Self::bound() == index && self.len() <= Self::bound() {
return false
return Err(())
}
// Cannot panic since `Self.bound() > 0`
self.0.truncate(Self::bound() - 1);
let maybe_removed = if self.is_full() {
// defensive-only: since we are at capacity, this is a noop.
self.0.truncate(Self::bound());
// if we truncate anything, it will be the last one.
self.0.pop()
} else {
None
};
// Cannot panic since `self.len() >= index`;
self.0.insert(index, element);
true
Ok(maybe_removed)
}
/// Move the position of an item from one location to another in the slice.
@@ -311,6 +347,20 @@ impl<T, S: Get<u32>> BoundedVec<T, S> {
self.0.resize(size, value);
}
/// Exactly the same semantics as [`Vec::extend`], but returns an error and does nothing if the
/// length of the outcome is larger than the bound.
pub fn try_extend(
&mut self,
with: impl IntoIterator<Item = T> + ExactSizeIterator,
) -> Result<(), ()> {
if with.len().saturating_add(self.len()) <= Self::bound() {
self.0.extend(with);
Ok(())
} else {
Err(())
}
}
/// Consumes self and mutates self via the given `mutate` function.
///
/// If the outcome of mutation is within bounds, `Some(Self)` is returned. Else, `None` is
@@ -522,7 +572,7 @@ where
#[cfg(test)]
pub mod test {
use super::*;
use crate::{traits::ConstU32, Twox128};
use crate::{bounded_vec, traits::ConstU32, Twox128};
use sp_io::TestExternalities;
crate::generate_storage_alias! { Prefix, Foo => Value<BoundedVec<u32, ConstU32<7>>> }
@@ -534,7 +584,7 @@ pub mod test {
#[test]
fn slide_works() {
let mut b: BoundedVec<u32, ConstU32<6>> = vec![0, 1, 2, 3, 4, 5].try_into().unwrap();
let mut b: BoundedVec<u32, ConstU32<6>> = bounded_vec![0, 1, 2, 3, 4, 5];
assert!(b.slide(1, 5));
assert_eq!(*b, vec![0, 2, 3, 4, 1, 5]);
assert!(b.slide(4, 0));
@@ -551,7 +601,7 @@ pub mod test {
assert!(!b.slide(7, 0));
assert_eq!(*b, vec![0, 2, 3, 4, 5, 1]);
let mut c: BoundedVec<u32, ConstU32<6>> = vec![0, 1, 2].try_into().unwrap();
let mut c: BoundedVec<u32, ConstU32<6>> = bounded_vec![0, 1, 2];
assert!(!c.slide(1, 5));
assert_eq!(*c, vec![0, 1, 2]);
assert!(!c.slide(4, 0));
@@ -564,7 +614,7 @@ pub mod test {
#[test]
fn slide_noops_work() {
let mut b: BoundedVec<u32, ConstU32<6>> = vec![0, 1, 2, 3, 4, 5].try_into().unwrap();
let mut b: BoundedVec<u32, ConstU32<6>> = bounded_vec![0, 1, 2, 3, 4, 5];
assert!(!b.slide(3, 3));
assert_eq!(*b, vec![0, 1, 2, 3, 4, 5]);
assert!(!b.slide(3, 4));
@@ -573,58 +623,59 @@ pub mod test {
#[test]
fn force_insert_keep_left_works() {
let mut b: BoundedVec<u32, ConstU32<4>> = vec![].try_into().unwrap();
assert!(!b.force_insert_keep_left(1, 10));
let mut b: BoundedVec<u32, ConstU32<4>> = bounded_vec![];
assert_eq!(b.force_insert_keep_left(1, 10), Err(()));
assert!(b.is_empty());
assert!(b.force_insert_keep_left(0, 30));
assert!(b.force_insert_keep_left(0, 10));
assert!(b.force_insert_keep_left(1, 20));
assert!(b.force_insert_keep_left(3, 40));
assert_eq!(b.force_insert_keep_left(0, 30), Ok(None));
assert_eq!(b.force_insert_keep_left(0, 10), Ok(None));
assert_eq!(b.force_insert_keep_left(1, 20), Ok(None));
assert_eq!(b.force_insert_keep_left(3, 40), Ok(None));
assert_eq!(*b, vec![10, 20, 30, 40]);
// at capacity.
assert!(!b.force_insert_keep_left(4, 41));
assert_eq!(b.force_insert_keep_left(4, 41), Err(()));
assert_eq!(*b, vec![10, 20, 30, 40]);
assert!(b.force_insert_keep_left(3, 31));
assert_eq!(b.force_insert_keep_left(3, 31), Ok(Some(40)));
assert_eq!(*b, vec![10, 20, 30, 31]);
assert!(b.force_insert_keep_left(1, 11));
assert_eq!(b.force_insert_keep_left(1, 11), Ok(Some(31)));
assert_eq!(*b, vec![10, 11, 20, 30]);
assert!(b.force_insert_keep_left(0, 1));
assert_eq!(b.force_insert_keep_left(0, 1), Ok(Some(30)));
assert_eq!(*b, vec![1, 10, 11, 20]);
let mut z: BoundedVec<u32, ConstU32<0>> = vec![].try_into().unwrap();
let mut z: BoundedVec<u32, ConstU32<0>> = bounded_vec![];
assert!(z.is_empty());
assert!(!z.force_insert_keep_left(0, 10));
assert_eq!(z.force_insert_keep_left(0, 10), Err(()));
assert!(z.is_empty());
}
#[test]
fn force_insert_keep_right_works() {
let mut b: BoundedVec<u32, ConstU32<4>> = vec![].try_into().unwrap();
assert!(!b.force_insert_keep_right(1, 10));
let mut b: BoundedVec<u32, ConstU32<4>> = bounded_vec![];
assert_eq!(b.force_insert_keep_right(1, 10), Err(()));
assert!(b.is_empty());
assert!(b.force_insert_keep_right(0, 30));
assert!(b.force_insert_keep_right(0, 10));
assert!(b.force_insert_keep_right(1, 20));
assert!(b.force_insert_keep_right(3, 40));
assert_eq!(b.force_insert_keep_right(0, 30), Ok(None));
assert_eq!(b.force_insert_keep_right(0, 10), Ok(None));
assert_eq!(b.force_insert_keep_right(1, 20), Ok(None));
assert_eq!(b.force_insert_keep_right(3, 40), Ok(None));
assert_eq!(*b, vec![10, 20, 30, 40]);
// at capacity.
assert!(!b.force_insert_keep_right(0, 0));
assert_eq!(b.force_insert_keep_right(0, 0), Err(()));
assert_eq!(*b, vec![10, 20, 30, 40]);
assert!(b.force_insert_keep_right(1, 11));
assert_eq!(b.force_insert_keep_right(1, 11), Ok(Some(10)));
assert_eq!(*b, vec![11, 20, 30, 40]);
assert!(b.force_insert_keep_right(3, 31));
assert_eq!(b.force_insert_keep_right(3, 31), Ok(Some(11)));
assert_eq!(*b, vec![20, 30, 31, 40]);
assert!(b.force_insert_keep_right(4, 41));
assert_eq!(b.force_insert_keep_right(4, 41), Ok(Some(20)));
assert_eq!(*b, vec![30, 31, 40, 41]);
assert!(!b.force_insert_keep_right(5, 69));
assert_eq!(b.force_insert_keep_right(5, 69), Err(()));
assert_eq!(*b, vec![30, 31, 40, 41]);
let mut z: BoundedVec<u32, ConstU32<0>> = vec![].try_into().unwrap();
let mut z: BoundedVec<u32, ConstU32<0>> = bounded_vec![];
assert!(z.is_empty());
assert!(!z.force_insert_keep_right(0, 10));
assert_eq!(z.force_insert_keep_right(0, 10), Err(()));
assert!(z.is_empty());
}
@@ -636,13 +687,13 @@ pub mod test {
#[test]
fn decode_len_works() {
TestExternalities::default().execute_with(|| {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
Foo::put(bounded);
assert_eq!(Foo::decode_len().unwrap(), 3);
});
TestExternalities::default().execute_with(|| {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
FooMap::insert(1, bounded);
assert_eq!(FooMap::decode_len(1).unwrap(), 3);
assert!(FooMap::decode_len(0).is_none());
@@ -650,7 +701,7 @@ pub mod test {
});
TestExternalities::default().execute_with(|| {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
FooDoubleMap::insert(1, 1, bounded);
assert_eq!(FooDoubleMap::decode_len(1, 1).unwrap(), 3);
assert!(FooDoubleMap::decode_len(2, 1).is_none());
@@ -661,7 +712,7 @@ pub mod test {
#[test]
fn try_insert_works() {
let mut bounded: BoundedVec<u32, ConstU32<4>> = vec![1, 2, 3].try_into().unwrap();
let mut bounded: BoundedVec<u32, ConstU32<4>> = bounded_vec![1, 2, 3];
bounded.try_insert(1, 0).unwrap();
assert_eq!(*bounded, vec![1, 0, 2, 3]);
@@ -685,13 +736,13 @@ pub mod test {
#[test]
#[should_panic(expected = "insertion index (is 9) should be <= len (is 3)")]
fn try_inert_panics_if_oob() {
let mut bounded: BoundedVec<u32, ConstU32<4>> = vec![1, 2, 3].try_into().unwrap();
let mut bounded: BoundedVec<u32, ConstU32<4>> = bounded_vec![1, 2, 3];
bounded.try_insert(9, 0).unwrap();
}
#[test]
fn try_push_works() {
let mut bounded: BoundedVec<u32, ConstU32<4>> = vec![1, 2, 3].try_into().unwrap();
let mut bounded: BoundedVec<u32, ConstU32<4>> = bounded_vec![1, 2, 3];
bounded.try_push(0).unwrap();
assert_eq!(*bounded, vec![1, 2, 3, 0]);
@@ -700,7 +751,7 @@ pub mod test {
#[test]
fn deref_coercion_works() {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
// these methods come from deref-ed vec.
assert_eq!(bounded.len(), 3);
assert!(bounded.iter().next().is_some());
@@ -709,7 +760,7 @@ pub mod test {
#[test]
fn try_mutate_works() {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3, 4, 5, 6].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3, 4, 5, 6];
let bounded = bounded.try_mutate(|v| v.push(7)).unwrap();
assert_eq!(bounded.len(), 7);
assert!(bounded.try_mutate(|v| v.push(8)).is_none());
@@ -717,13 +768,13 @@ pub mod test {
#[test]
fn slice_indexing_works() {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3, 4, 5, 6].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3, 4, 5, 6];
assert_eq!(&bounded[0..=2], &[1, 2, 3]);
}
#[test]
fn vec_eq_works() {
let bounded: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3, 4, 5, 6].try_into().unwrap();
let bounded: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3, 4, 5, 6];
assert_eq!(bounded, vec![1, 2, 3, 4, 5, 6]);
}
@@ -738,7 +789,7 @@ pub mod test {
#[test]
fn can_be_collected() {
let b1: BoundedVec<u32, ConstU32<5>> = vec![1, 2, 3, 4].try_into().unwrap();
let b1: BoundedVec<u32, ConstU32<5>> = bounded_vec![1, 2, 3, 4];
let b2: BoundedVec<u32, ConstU32<5>> = b1.iter().map(|x| x + 1).try_collect().unwrap();
assert_eq!(b2, vec![2, 3, 4, 5]);
@@ -777,8 +828,8 @@ pub mod test {
#[test]
fn eq_works() {
// of same type
let b1: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let b2: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let b1: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
let b2: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
assert_eq!(b1, b2);
// of different type, but same value and bound.
@@ -786,19 +837,41 @@ pub mod test {
B1: u32 = 7;
B2: u32 = 7;
}
let b1: BoundedVec<u32, B1> = vec![1, 2, 3].try_into().unwrap();
let b2: BoundedVec<u32, B2> = vec![1, 2, 3].try_into().unwrap();
let b1: BoundedVec<u32, B1> = bounded_vec![1, 2, 3];
let b2: BoundedVec<u32, B2> = bounded_vec![1, 2, 3];
assert_eq!(b1, b2);
}
#[test]
fn ord_works() {
use std::cmp::Ordering;
let b1: BoundedVec<u32, ConstU32<7>> = vec![1, 2, 3].try_into().unwrap();
let b2: BoundedVec<u32, ConstU32<7>> = vec![1, 3, 2].try_into().unwrap();
let b1: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 2, 3];
let b2: BoundedVec<u32, ConstU32<7>> = bounded_vec![1, 3, 2];
// ordering for vec is lexicographic.
assert_eq!(b1.cmp(&b2), Ordering::Less);
assert_eq!(b1.cmp(&b2), b1.into_inner().cmp(&b2.into_inner()));
}
#[test]
fn try_extend_works() {
let mut b: BoundedVec<u32, ConstU32<5>> = bounded_vec![1, 2, 3];
assert!(b.try_extend(vec![4].into_iter()).is_ok());
assert_eq!(*b, vec![1, 2, 3, 4]);
assert!(b.try_extend(vec![5].into_iter()).is_ok());
assert_eq!(*b, vec![1, 2, 3, 4, 5]);
assert!(b.try_extend(vec![6].into_iter()).is_err());
assert_eq!(*b, vec![1, 2, 3, 4, 5]);
let mut b: BoundedVec<u32, ConstU32<5>> = bounded_vec![1, 2, 3];
assert!(b.try_extend(vec![4, 5].into_iter()).is_ok());
assert_eq!(*b, vec![1, 2, 3, 4, 5]);
let mut b: BoundedVec<u32, ConstU32<5>> = bounded_vec![1, 2, 3];
assert!(b.try_extend(vec![4, 5, 6].into_iter()).is_err());
assert_eq!(*b, vec![1, 2, 3]);
}
}
+2
View File
@@ -58,6 +58,8 @@ pub use misc::{
PreimageRecipient, PrivilegeCmp, SameOrOther, Time, TryCollect, TryDrop, UnixTime,
WrapperKeepOpaque, WrapperOpaque,
};
#[doc(hidden)]
pub use misc::{DEFENSIVE_OP_INTERNAL_ERROR, DEFENSIVE_OP_PUBLIC_ERROR};
mod stored_map;
pub use stored_map::{StorageMapShim, StoredMap};
+43 -100
View File
@@ -24,8 +24,34 @@ use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, Saturating};
use sp_runtime::{traits::Block as BlockT, DispatchError};
use sp_std::{cmp::Ordering, prelude::*};
const DEFENSIVE_OP_PUBLIC_ERROR: &'static str = "a defensive failure has been triggered; please report the block number at https://github.com/paritytech/substrate/issues";
const DEFENSIVE_OP_INTERNAL_ERROR: &'static str = "Defensive failure has been triggered!";
#[doc(hidden)]
pub const DEFENSIVE_OP_PUBLIC_ERROR: &'static str = "a defensive failure has been triggered; please report the block number at https://github.com/paritytech/substrate/issues";
#[doc(hidden)]
pub const DEFENSIVE_OP_INTERNAL_ERROR: &'static str = "Defensive failure has been triggered!";
/// Generic function to mark an execution path as ONLY defensive.
///
/// Similar to mark a match arm or `if/else` branch as `unreachable!`.
#[macro_export]
macro_rules! defensive {
() => {
frame_support::log::error!(
target: "runtime",
"{}",
$crate::traits::misc::DEFENSIVE_OP_PUBLIC_ERROR
);
debug_assert!(false, "{}", $crate::traits::misc::DEFENSIVE_OP_INTERNAL_ERROR);
};
($error:tt) => {
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
$crate::traits::misc::DEFENSIVE_OP_PUBLIC_ERROR,
$error
);
debug_assert!(false, "{}: {:?}", $crate::traits::misc::DEFENSIVE_OP_INTERNAL_ERROR, $error);
}
}
/// Prelude module for all defensive traits to be imported at once.
pub mod defensive_prelude {
@@ -116,12 +142,7 @@ impl<T> Defensive<T> for Option<T> {
match self {
Some(inner) => inner,
None => {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR
);
defensive!();
or
},
}
@@ -131,12 +152,7 @@ impl<T> Defensive<T> for Option<T> {
match self {
Some(inner) => inner,
None => {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR
);
defensive!();
f()
},
}
@@ -149,12 +165,7 @@ impl<T> Defensive<T> for Option<T> {
match self {
Some(inner) => inner,
None => {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR
);
defensive!();
Default::default()
},
}
@@ -164,12 +175,7 @@ impl<T> Defensive<T> for Option<T> {
match self {
Some(inner) => Some(inner),
None => {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR
);
defensive!();
None
},
}
@@ -181,13 +187,7 @@ impl<T, E: sp_std::fmt::Debug> Defensive<T> for Result<T, E> {
match self {
Ok(inner) => inner,
Err(e) => {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
or
},
}
@@ -197,13 +197,7 @@ impl<T, E: sp_std::fmt::Debug> Defensive<T> for Result<T, E> {
match self {
Ok(inner) => inner,
Err(e) => {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
f()
},
}
@@ -216,13 +210,7 @@ impl<T, E: sp_std::fmt::Debug> Defensive<T> for Result<T, E> {
match self {
Ok(inner) => inner,
Err(e) => {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
Default::default()
},
}
@@ -232,13 +220,7 @@ impl<T, E: sp_std::fmt::Debug> Defensive<T> for Result<T, E> {
match self {
Ok(inner) => Ok(inner),
Err(e) => {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
Err(e)
},
}
@@ -248,13 +230,7 @@ impl<T, E: sp_std::fmt::Debug> Defensive<T> for Result<T, E> {
impl<T, E: sp_std::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F> {
self.map_err(|e| {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
o(e)
})
}
@@ -262,13 +238,7 @@ impl<T, E: sp_std::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
self.map_or_else(
|e| {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
default(e)
},
f,
@@ -279,13 +249,7 @@ impl<T, E: sp_std::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
match self {
Ok(inner) => Some(inner),
Err(e) => {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
None
},
}
@@ -295,13 +259,7 @@ impl<T, E: sp_std::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
match self {
Ok(inner) => Ok(f(inner)),
Err(e) => {
debug_assert!(false, "{}: {:?}", DEFENSIVE_OP_INTERNAL_ERROR, e);
frame_support::log::error!(
target: "runtime",
"{}: {:?}",
DEFENSIVE_OP_PUBLIC_ERROR,
e
);
defensive!(e);
Err(e)
},
}
@@ -312,12 +270,7 @@ impl<T> DefensiveOption<T> for Option<T> {
fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
self.map_or_else(
|| {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR,
);
defensive!();
default()
},
f,
@@ -326,12 +279,7 @@ impl<T> DefensiveOption<T> for Option<T> {
fn defensive_ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
self.ok_or_else(|| {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR,
);
defensive!();
err()
})
}
@@ -340,12 +288,7 @@ impl<T> DefensiveOption<T> for Option<T> {
match self {
Some(inner) => Some(f(inner)),
None => {
debug_assert!(false, "{}", DEFENSIVE_OP_INTERNAL_ERROR);
frame_support::log::error!(
target: "runtime",
"{}",
DEFENSIVE_OP_PUBLIC_ERROR,
);
defensive!();
None
},
}