From 95593735b7bad451e029e885f46538d9c219bec6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 6 Jan 2022 15:06:55 +0100 Subject: [PATCH 01/30] Add Bounder trait Implement bounder for primitive types --- packages/storage-plus/src/keys.rs | 84 +++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index e4240abb1..89677c934 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -3,6 +3,7 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::int_key::CwIntKey; +use crate::Bound; #[derive(Debug)] pub enum Key<'a> { @@ -300,6 +301,89 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); +pub trait Bounder<'a> { + fn inclusive_bound(&self) -> Option; + fn exclusive_bound(&self) -> Option; +} + +impl<'a> Bounder<'a> for () { + fn inclusive_bound(&self) -> Option { + None + } + fn exclusive_bound(&self) -> Option { + None + } +} + +impl<'a> Bounder<'a> for &'a [u8] { + fn inclusive_bound(&self) -> Option { + Some(Bound::inclusive(self.to_vec())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::exclusive(self.to_vec())) + } +} + +impl<'a> Bounder<'a> for &'a str { + fn inclusive_bound(&self) -> Option { + Some(Bound::inclusive(self.as_bytes().to_vec())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::exclusive(self.as_bytes().to_vec())) + } +} + +impl<'a> Bounder<'a> for String { + fn inclusive_bound(&self) -> Option { + Some(Bound::inclusive(self.as_bytes().to_vec())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::exclusive(self.as_bytes().to_vec())) + } +} + +impl<'a> Bounder<'a> for Vec { + fn inclusive_bound(&self) -> Option { + Some(Bound::inclusive(self.clone())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::exclusive(self.clone())) + } +} + +impl<'a> Bounder<'a> for &'a Addr { + fn inclusive_bound(&self) -> Option { + Some(Bound::Inclusive(self.as_ref().into())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::Exclusive(self.as_ref().into())) + } +} + +impl<'a> Bounder<'a> for Addr { + fn inclusive_bound(&self) -> Option { + Some(Bound::Inclusive(self.as_ref().into())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::Exclusive(self.as_ref().into())) + } +} + +macro_rules! integer_bound { + (for $($t:ty),+) => { + $(impl<'a> Bounder<'a> for $t { + fn inclusive_bound(&self) -> Option { + Some(Bound::inclusive_int(*self)) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::exclusive_int(*self)) + } + })* + } +} + +integer_bound!(for i8, u8, i16, u16, i32, u32, i64, u64); + #[cfg(test)] mod test { use super::*; From 3a57e4fdaa5e1212299a509633ba32616dbb9dd5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 6 Jan 2022 15:12:02 +0100 Subject: [PATCH 02/30] Implement Bounder for composite types --- packages/storage-plus/src/keys.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 89677c934..2a1adf991 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -324,6 +324,24 @@ impl<'a> Bounder<'a> for &'a [u8] { } } +impl<'a, T: Prefixer<'a>, U: Prefixer<'a>> Bounder<'a> for (T, U) { + fn inclusive_bound(&self) -> Option { + Some(Bound::Inclusive(self.joined_prefix())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::Exclusive(self.joined_prefix())) + } +} + +impl<'a, T: Prefixer<'a>, U: Prefixer<'a>, V: Prefixer<'a>> Bounder<'a> for (T, U, V) { + fn inclusive_bound(&self) -> Option { + Some(Bound::Inclusive(self.joined_prefix())) + } + fn exclusive_bound(&self) -> Option { + Some(Bound::Exclusive(self.joined_prefix())) + } +} + impl<'a> Bounder<'a> for &'a str { fn inclusive_bound(&self) -> Option { Some(Bound::inclusive(self.as_bytes().to_vec())) From 60c42b6572e6e01d124b98fd4e94f85ff04c9b63 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 08:20:39 +0100 Subject: [PATCH 03/30] Implement type safe bounds for range --- packages/storage-plus/src/keys.rs | 2 +- packages/storage-plus/src/map.rs | 24 ++++++++++++- packages/storage-plus/src/prefix.rs | 55 ++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 2a1adf991..7a361c46d 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -301,7 +301,7 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); -pub trait Bounder<'a> { +pub trait Bounder<'a>: Prefixer<'a> { fn inclusive_bound(&self) -> Option; fn exclusive_bound(&self) -> Option; } diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 45a89c294..4352baf24 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -9,8 +9,9 @@ use crate::helpers::query_raw; use crate::iter_helpers::{deserialize_kv, deserialize_v}; #[cfg(feature = "iterator")] use crate::keys::Prefixer; -use crate::keys::{Key, PrimaryKey}; +use crate::keys::{Bounder, Key, PrimaryKey}; use crate::path::Path; +use crate::prefix::Bound2; #[cfg(feature = "iterator")] use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; use cosmwasm_std::{from_slice, Addr, QuerierWrapper, StdError, StdResult, Storage}; @@ -244,6 +245,27 @@ where } } +#[cfg(feature = "iterator")] +impl<'a, K, T> Map<'a, K, T> +where + T: Serialize + DeserializeOwned, + K: PrimaryKey<'a> + KeyDeserialize + Bounder<'a>, +{ + pub fn range2<'c>( + &self, + store: &'c dyn Storage, + min: Option>, + max: Option>, + order: cosmwasm_std::Order, + ) -> Box> + 'c> + where + T: 'c, + K::Output: 'static, + { + self.no_prefix().range2(store, min, max, order) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 38e4b7c78..bfc5b47cc 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -10,7 +10,7 @@ use crate::de::KeyDeserialize; use crate::helpers::{namespaces_with_key, nested_namespaces_with_key}; use crate::int_key::CwIntKey; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; -use crate::keys::Key; +use crate::keys::{Bounder, Key}; use crate::{Endian, Prefixer}; /// Bound is used to defines the two ends of a range, more explicit than Option @@ -45,6 +45,29 @@ impl Bound { } } +#[derive(Clone, Debug)] +pub enum Bound2<'a, K: Bounder<'a>> { + Inclusive((K, PhantomData<&'a bool>)), + Exclusive((K, PhantomData<&'a bool>)), +} + +impl<'a, K: Bounder<'a>> Bound2<'a, K> { + pub fn inclusive>(k: T) -> Self { + Self::Inclusive((k.into(), PhantomData)) + } + + pub fn exclusive>(k: T) -> Self { + Self::Exclusive((k.into(), PhantomData)) + } + + pub fn to_bound(&self) -> Bound { + match self { + Bound2::Exclusive((k, _)) => Bound::Exclusive(k.joined_prefix()), + Bound2::Inclusive((k, _)) => Bound::Inclusive(k.joined_prefix()), + } + } +} + #[derive(Clone, Debug)] pub enum PrefixBound<'a, K: Prefixer<'a>> { Inclusive((K, PhantomData<&'a bool>)), @@ -215,6 +238,36 @@ where } } +impl<'p, K, T> Prefix +where + K: KeyDeserialize + Bounder<'p>, + T: Serialize + DeserializeOwned, +{ + pub fn range2<'a>( + &self, + store: &'a dyn Storage, + min: Option>, + max: Option>, + order: Order, + ) -> Box> + 'a> + where + T: 'a, + K::Output: 'static, + { + let de_fn = self.de_fn_kv; + let pk_name = self.pk_name.clone(); + let mapped = range_with_prefix( + store, + &self.storage_prefix, + min.map(|b| b.to_bound()), + max.map(|b| b.to_bound()), + order, + ) + .map(move |kv| (de_fn)(store, &pk_name, kv)); + Box::new(mapped) + } +} + pub fn range_with_prefix<'a>( storage: &'a dyn Storage, namespace: &[u8], From f362fdf512a085ca68ae04067fe4a5734cce1d6f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 08:23:27 +0100 Subject: [PATCH 04/30] Move Bounder impls to experimental Bound2 --- packages/storage-plus/src/keys.rs | 90 ++++++++++++++++--------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 7a361c46d..b84bb4ffa 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -3,7 +3,7 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::int_key::CwIntKey; -use crate::Bound; +use crate::prefix::Bound2; #[derive(Debug)] pub enum Key<'a> { @@ -301,100 +301,102 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); -pub trait Bounder<'a>: Prefixer<'a> { - fn inclusive_bound(&self) -> Option; - fn exclusive_bound(&self) -> Option; +pub trait Bounder<'a>: Prefixer<'a> + Sized { + fn inclusive_bound(&self) -> Option>; + fn exclusive_bound(&self) -> Option>; } impl<'a> Bounder<'a> for () { - fn inclusive_bound(&self) -> Option { + fn inclusive_bound(&self) -> Option> { None } - fn exclusive_bound(&self) -> Option { + fn exclusive_bound(&self) -> Option> { None } } impl<'a> Bounder<'a> for &'a [u8] { - fn inclusive_bound(&self) -> Option { - Some(Bound::inclusive(self.to_vec())) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(*self)) } - fn exclusive_bound(&self) -> Option { - Some(Bound::exclusive(self.to_vec())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(*self)) } } -impl<'a, T: Prefixer<'a>, U: Prefixer<'a>> Bounder<'a> for (T, U) { - fn inclusive_bound(&self) -> Option { - Some(Bound::Inclusive(self.joined_prefix())) +impl<'a, T: Prefixer<'a> + Clone, U: Prefixer<'a> + Clone> Bounder<'a> for (T, U) { + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(self.clone())) } - fn exclusive_bound(&self) -> Option { - Some(Bound::Exclusive(self.joined_prefix())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(self.clone())) } } -impl<'a, T: Prefixer<'a>, U: Prefixer<'a>, V: Prefixer<'a>> Bounder<'a> for (T, U, V) { - fn inclusive_bound(&self) -> Option { - Some(Bound::Inclusive(self.joined_prefix())) +impl<'a, T: Prefixer<'a> + Clone, U: Prefixer<'a> + Clone, V: Prefixer<'a> + Clone> Bounder<'a> + for (T, U, V) +{ + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(self.clone())) } - fn exclusive_bound(&self) -> Option { - Some(Bound::Exclusive(self.joined_prefix())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(self.clone())) } } impl<'a> Bounder<'a> for &'a str { - fn inclusive_bound(&self) -> Option { - Some(Bound::inclusive(self.as_bytes().to_vec())) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(*self)) } - fn exclusive_bound(&self) -> Option { - Some(Bound::exclusive(self.as_bytes().to_vec())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(*self)) } } impl<'a> Bounder<'a> for String { - fn inclusive_bound(&self) -> Option { - Some(Bound::inclusive(self.as_bytes().to_vec())) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(self.clone())) } - fn exclusive_bound(&self) -> Option { - Some(Bound::exclusive(self.as_bytes().to_vec())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(self.clone())) } } impl<'a> Bounder<'a> for Vec { - fn inclusive_bound(&self) -> Option { - Some(Bound::inclusive(self.clone())) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(self.clone())) } - fn exclusive_bound(&self) -> Option { - Some(Bound::exclusive(self.clone())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(self.clone())) } } impl<'a> Bounder<'a> for &'a Addr { - fn inclusive_bound(&self) -> Option { - Some(Bound::Inclusive(self.as_ref().into())) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(*self)) } - fn exclusive_bound(&self) -> Option { - Some(Bound::Exclusive(self.as_ref().into())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(*self)) } } impl<'a> Bounder<'a> for Addr { - fn inclusive_bound(&self) -> Option { - Some(Bound::Inclusive(self.as_ref().into())) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(self.clone())) } - fn exclusive_bound(&self) -> Option { - Some(Bound::Exclusive(self.as_ref().into())) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(self.clone())) } } macro_rules! integer_bound { (for $($t:ty),+) => { $(impl<'a> Bounder<'a> for $t { - fn inclusive_bound(&self) -> Option { - Some(Bound::inclusive_int(*self)) + fn inclusive_bound(&self) -> Option> { + Some(Bound2::inclusive(*self)) } - fn exclusive_bound(&self) -> Option { - Some(Bound::exclusive_int(*self)) + fn exclusive_bound(&self) -> Option> { + Some(Bound2::exclusive(*self)) } })* } From b70b387123b957fd04c4b8ad888048388c69b08a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 09:32:20 +0100 Subject: [PATCH 05/30] Use proper joined key for bounds --- packages/storage-plus/src/keys.rs | 17 +++++++++++++---- packages/storage-plus/src/prefix.rs | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index b84bb4ffa..b6e9fc9ad 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -301,7 +301,7 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); -pub trait Bounder<'a>: Prefixer<'a> + Sized { +pub trait Bounder<'a>: PrimaryKey<'a> + Sized { fn inclusive_bound(&self) -> Option>; fn exclusive_bound(&self) -> Option>; } @@ -324,7 +324,12 @@ impl<'a> Bounder<'a> for &'a [u8] { } } -impl<'a, T: Prefixer<'a> + Clone, U: Prefixer<'a> + Clone> Bounder<'a> for (T, U) { +impl< + 'a, + T: PrimaryKey<'a> + KeyDeserialize + Prefixer<'a> + Clone, + U: PrimaryKey<'a> + KeyDeserialize + Clone, + > Bounder<'a> for (T, U) +{ fn inclusive_bound(&self) -> Option> { Some(Bound2::inclusive(self.clone())) } @@ -333,8 +338,12 @@ impl<'a, T: Prefixer<'a> + Clone, U: Prefixer<'a> + Clone> Bounder<'a> for (T, U } } -impl<'a, T: Prefixer<'a> + Clone, U: Prefixer<'a> + Clone, V: Prefixer<'a> + Clone> Bounder<'a> - for (T, U, V) +impl< + 'a, + T: PrimaryKey<'a> + Prefixer<'a> + Clone, + U: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize + Clone, + V: PrimaryKey<'a> + KeyDeserialize + Clone, + > Bounder<'a> for (T, U, V) { fn inclusive_bound(&self) -> Option> { Some(Bound2::inclusive(self.clone())) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index bfc5b47cc..234b20ce3 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -62,8 +62,8 @@ impl<'a, K: Bounder<'a>> Bound2<'a, K> { pub fn to_bound(&self) -> Bound { match self { - Bound2::Exclusive((k, _)) => Bound::Exclusive(k.joined_prefix()), - Bound2::Inclusive((k, _)) => Bound::Inclusive(k.joined_prefix()), + Bound2::Exclusive((k, _)) => Bound::Exclusive(k.joined_key()), + Bound2::Inclusive((k, _)) => Bound::Inclusive(k.joined_key()), } } } From ae80d8306497b02ce8b04cc6069fa9bd2811b930 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 09:56:31 +0100 Subject: [PATCH 06/30] Remove self reference --- packages/storage-plus/src/keys.rs | 80 +++++++++++++++---------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index b6e9fc9ad..e10e1b02a 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -302,25 +302,25 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); pub trait Bounder<'a>: PrimaryKey<'a> + Sized { - fn inclusive_bound(&self) -> Option>; - fn exclusive_bound(&self) -> Option>; + fn inclusive_bound(self) -> Option>; + fn exclusive_bound(self) -> Option>; } impl<'a> Bounder<'a> for () { - fn inclusive_bound(&self) -> Option> { + fn inclusive_bound(self) -> Option> { None } - fn exclusive_bound(&self) -> Option> { + fn exclusive_bound(self) -> Option> { None } } impl<'a> Bounder<'a> for &'a [u8] { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(*self)) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(*self)) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } @@ -330,11 +330,11 @@ impl< U: PrimaryKey<'a> + KeyDeserialize + Clone, > Bounder<'a> for (T, U) { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(self.clone())) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(self.clone())) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } @@ -345,67 +345,67 @@ impl< V: PrimaryKey<'a> + KeyDeserialize + Clone, > Bounder<'a> for (T, U, V) { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(self.clone())) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(self.clone())) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } impl<'a> Bounder<'a> for &'a str { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(*self)) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(*self)) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } impl<'a> Bounder<'a> for String { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(self.clone())) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(self.clone())) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } impl<'a> Bounder<'a> for Vec { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(self.clone())) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(self.clone())) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } impl<'a> Bounder<'a> for &'a Addr { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(*self)) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(*self)) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } impl<'a> Bounder<'a> for Addr { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(self.clone())) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(self.clone())) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } } macro_rules! integer_bound { (for $($t:ty),+) => { $(impl<'a> Bounder<'a> for $t { - fn inclusive_bound(&self) -> Option> { - Some(Bound2::inclusive(*self)) + fn inclusive_bound(self) -> Option> { + Some(Bound2::inclusive(self)) } - fn exclusive_bound(&self) -> Option> { - Some(Bound2::exclusive(*self)) + fn exclusive_bound(self) -> Option> { + Some(Bound2::exclusive(self)) } })* } From 7d61cfdc133aeb68ecfebfa0cd88d96674797d61 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 09:57:15 +0100 Subject: [PATCH 07/30] Add range2 simple key tests --- packages/storage-plus/src/map.rs | 159 +++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 4352baf24..91f8f2132 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -544,6 +544,65 @@ mod test { assert_eq!(all, vec![(b"john".to_vec(), data)]); } + #[test] + #[cfg(feature = "iterator")] + fn range2_simple_string_key() { + let mut store = MockStorage::new(); + + // save and load on three keys + let data = Data { + name: "John".to_string(), + age: 32, + }; + PEOPLE.save(&mut store, b"john", &data).unwrap(); + + let data2 = Data { + name: "Jim".to_string(), + age: 44, + }; + PEOPLE.save(&mut store, b"jim", &data2).unwrap(); + + let data3 = Data { + name: "Ada".to_string(), + age: 23, + }; + PEOPLE.save(&mut store, b"ada", &data3).unwrap(); + + // let's try to iterate! + let all: StdResult> = PEOPLE + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(3, all.len()); + assert_eq!( + all, + vec![ + (b"ada".to_vec(), data3), + (b"jim".to_vec(), data2.clone()), + (b"john".to_vec(), data.clone()) + ] + ); + + // let's try to iterate over a range + let all: StdResult> = PEOPLE + .range2(&store, b"j".inclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!( + all, + vec![(b"jim".to_vec(), data2), (b"john".to_vec(), data.clone())] + ); + + // let's try to iterate over a more restrictive range + let all: StdResult> = PEOPLE + .range2(&store, b"jo".inclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(b"john".to_vec(), data)]); + } + #[test] #[cfg(feature = "iterator")] fn range_simple_integer_key() { @@ -596,6 +655,48 @@ mod test { assert_eq!(1, all.len()); assert_eq!(all, vec![(1234, data)]); } + #[test] + #[cfg(feature = "iterator")] + fn range2_simple_integer_key() { + let mut store = MockStorage::new(); + + // save and load on two keys + let data = Data { + name: "John".to_string(), + age: 32, + }; + PEOPLE_ID.save(&mut store, 1234, &data).unwrap(); + + let data2 = Data { + name: "Jim".to_string(), + age: 44, + }; + PEOPLE_ID.save(&mut store, 56, &data2).unwrap(); + + // let's try to iterate! + let all: StdResult> = PEOPLE_ID + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!(all, vec![(56, data2.clone()), (1234, data.clone())]); + + // let's try to iterate over a range + let all: StdResult> = PEOPLE_ID + .range2(&store, 56u32.inclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!(all, vec![(56, data2), (1234, data.clone())]); + + // let's try to iterate over a more restrictive range + let all: StdResult> = PEOPLE_ID + .range2(&store, 57u32.inclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(1234, data)]); + } #[test] #[cfg(feature = "iterator")] @@ -660,6 +761,64 @@ mod test { assert_eq!(all, vec![(50, data3)]); } + #[test] + #[cfg(feature = "iterator")] + fn range2_simple_signed_integer_key() { + let mut store = MockStorage::new(); + + // save and load on three keys + let data = Data { + name: "John".to_string(), + age: 32, + }; + SIGNED_ID.save(&mut store, -1234, &data).unwrap(); + + let data2 = Data { + name: "Jim".to_string(), + age: 44, + }; + SIGNED_ID.save(&mut store, -56, &data2).unwrap(); + + let data3 = Data { + name: "Jules".to_string(), + age: 55, + }; + SIGNED_ID.save(&mut store, 50, &data3).unwrap(); + + // let's try to iterate! + let all: StdResult> = SIGNED_ID + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(3, all.len()); + // order is correct + assert_eq!( + all, + vec![(-1234, data), (-56, data2.clone()), (50, data3.clone())] + ); + + // let's try to iterate over a range + let all: StdResult> = SIGNED_ID + .range2(&store, (-56i32).inclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!(all, vec![(-56, data2), (50, data3.clone())]); + + // let's try to iterate over a more restrictive range + let all: StdResult> = SIGNED_ID + .range2( + &store, + (-55i32).inclusive_bound(), + 50i32.inclusive_bound(), + Order::Descending, + ) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(50, data3)]); + } + #[test] #[cfg(feature = "iterator")] fn range_signed_integer_key_migration() { From 25c340b4c5f12f12a2d35cf6fcb22867486d7b17 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 13:24:36 +0100 Subject: [PATCH 08/30] Add range2 composite key tests --- packages/storage-plus/src/map.rs | 166 +++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 91f8f2132..28a7d89dd 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -977,6 +977,71 @@ mod test { ); } + #[test] + #[cfg(feature = "iterator")] + fn range2_composite_key() { + let mut store = MockStorage::new(); + + // save and load on three keys, one under different owner + ALLOWANCE + .save(&mut store, (b"owner", b"spender"), &1000) + .unwrap(); + ALLOWANCE + .save(&mut store, (b"owner", b"spender2"), &3000) + .unwrap(); + ALLOWANCE + .save(&mut store, (b"owner2", b"spender"), &5000) + .unwrap(); + + // let's try to iterate! + let all: StdResult> = ALLOWANCE + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(3, all.len()); + assert_eq!( + all, + vec![ + ((b"owner".to_vec(), b"spender".to_vec()), 1000), + ((b"owner".to_vec(), b"spender2".to_vec()), 3000), + ((b"owner2".to_vec(), b"spender".to_vec()), 5000) + ] + ); + + // let's try to iterate over a prefix + let all: StdResult> = ALLOWANCE + .prefix(b"owner") + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!( + all, + vec![(b"spender".to_vec(), 1000), (b"spender2".to_vec(), 3000),] + ); + + // let's try to iterate over a prefixed restricted inclusive range + let all: StdResult> = ALLOWANCE + .prefix(b"owner") + .range2(&store, b"spender".inclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!( + all, + vec![(b"spender".to_vec(), 1000), (b"spender2".to_vec(), 3000),] + ); + + // let's try to iterate over a prefixed restricted exclusive range + let all: StdResult> = ALLOWANCE + .prefix(b"owner") + .range2(&store, b"spender".exclusive_bound(), None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(b"spender2".to_vec(), 3000),]); + } + #[test] #[cfg(feature = "iterator")] fn range_raw_triple_key() { @@ -1122,6 +1187,107 @@ mod test { ); } + #[test] + #[cfg(feature = "iterator")] + fn range2_triple_key() { + let mut store = MockStorage::new(); + + // save and load on three keys, one under different owner + TRIPLE + .save(&mut store, (b"owner", 9u8, "recipient"), &1000) + .unwrap(); + TRIPLE + .save(&mut store, (b"owner", 9u8, "recipient2"), &3000) + .unwrap(); + TRIPLE + .save(&mut store, (b"owner", 10u8, "recipient3"), &3000) + .unwrap(); + TRIPLE + .save(&mut store, (b"owner2", 9u8, "recipient"), &5000) + .unwrap(); + + // let's try to iterate! + let all: StdResult> = TRIPLE + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(4, all.len()); + assert_eq!( + all, + vec![ + ((b"owner".to_vec(), 9, "recipient".to_string()), 1000), + ((b"owner".to_vec(), 9, "recipient2".to_string()), 3000), + ((b"owner".to_vec(), 10, "recipient3".to_string()), 3000), + ((b"owner2".to_vec(), 9, "recipient".to_string()), 5000) + ] + ); + + // let's iterate over a sub_prefix + let all: StdResult> = TRIPLE + .sub_prefix(b"owner") + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(3, all.len()); + assert_eq!( + all, + vec![ + ((9, "recipient".to_string()), 1000), + ((9, "recipient2".to_string()), 3000), + ((10, "recipient3".to_string()), 3000), + ] + ); + + // let's iterate over a prefix + let all: StdResult> = TRIPLE + .prefix((b"owner", 9)) + .range2(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!( + all, + vec![ + ("recipient".to_string(), 1000), + ("recipient2".to_string(), 3000), + ] + ); + + // let's try to iterate over a prefixed restricted inclusive range + let all: StdResult> = TRIPLE + .prefix((b"owner", 9)) + .range2( + &store, + "recipient".inclusive_bound(), + None, + Order::Ascending, + ) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!( + all, + vec![ + ("recipient".to_string(), 1000), + ("recipient2".to_string(), 3000), + ] + ); + + // let's try to iterate over a prefixed restricted exclusive range + let all: StdResult> = TRIPLE + .prefix((b"owner", 9)) + .range2( + &store, + "recipient".exclusive_bound(), + None, + Order::Ascending, + ) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![("recipient2".to_string(), 3000),]); + } + #[test] fn basic_update() { let mut store = MockStorage::new(); From 73f1d654aaec1847414c609008c20cffed814203 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 15:59:30 +0100 Subject: [PATCH 09/30] Simplify Bound2 traits --- packages/storage-plus/src/prefix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 234b20ce3..e3f7b618a 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -11,7 +11,7 @@ use crate::helpers::{namespaces_with_key, nested_namespaces_with_key}; use crate::int_key::CwIntKey; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; use crate::keys::{Bounder, Key}; -use crate::{Endian, Prefixer}; +use crate::{Endian, Prefixer, PrimaryKey}; /// Bound is used to defines the two ends of a range, more explicit than Option /// None means that we don't limit that side of the range at all. @@ -46,7 +46,7 @@ impl Bound { } #[derive(Clone, Debug)] -pub enum Bound2<'a, K: Bounder<'a>> { +pub enum Bound2<'a, K: PrimaryKey<'a>> { Inclusive((K, PhantomData<&'a bool>)), Exclusive((K, PhantomData<&'a bool>)), } From 2385b9da601527ad90aba8f1386ce696386c1c90 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 18:18:48 +0100 Subject: [PATCH 10/30] rename lifetime for clarity --- packages/storage-plus/src/prefix.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index e3f7b618a..0f78911bf 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -238,16 +238,16 @@ where } } -impl<'p, K, T> Prefix +impl<'b, K, T> Prefix where - K: KeyDeserialize + Bounder<'p>, + K: KeyDeserialize + Bounder<'b>, T: Serialize + DeserializeOwned, { pub fn range2<'a>( &self, store: &'a dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'a> where From 1634af15d642ef4e39b27f5a558860637ed2b51e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 19:32:27 +0100 Subject: [PATCH 11/30] Add specific type parameter for Prefix bound --- packages/storage-plus/src/map.rs | 6 +++--- packages/storage-plus/src/prefix.rs | 17 +++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 28a7d89dd..7b686ccc4 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -116,11 +116,11 @@ where T: Serialize + DeserializeOwned, K: PrimaryKey<'a>, { - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.namespace, &p.prefix()) } - pub fn prefix(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.namespace, &p.prefix()) } } @@ -240,7 +240,7 @@ where self.no_prefix().keys(store, min, max, order) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.namespace, &[]) } } diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 0f78911bf..74c97fd52 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -113,7 +113,7 @@ pub fn default_deserializer_kv( } #[derive(Clone)] -pub struct Prefix +pub struct Prefix> where K: KeyDeserialize, T: Serialize + DeserializeOwned, @@ -121,7 +121,7 @@ where /// all namespaces prefixes and concatenated with the key storage_prefix: Vec, // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed - data: PhantomData, + data: PhantomData<(T, B)>, pk_name: Vec, de_fn_kv: DeserializeKvFn, de_fn_v: DeserializeVFn, @@ -139,7 +139,7 @@ where } } -impl Prefix +impl Prefix where K: KeyDeserialize, T: Serialize + DeserializeOwned, @@ -238,16 +238,17 @@ where } } -impl<'b, K, T> Prefix +impl<'b, K, T, B> Prefix where - K: KeyDeserialize + Bounder<'b>, + B: Bounder<'b>, + K: KeyDeserialize, T: Serialize + DeserializeOwned, { pub fn range2<'a>( &self, store: &'a dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'a> where @@ -382,7 +383,7 @@ mod test { // manually create this - not testing nested prefixes here let prefix: Prefix, u64> = Prefix { storage_prefix: b"foo".to_vec(), - data: PhantomData::, + data: PhantomData::<(u64, _)>, pk_name: vec![], de_fn_kv: |_, _, kv| deserialize_kv::, u64>(kv), de_fn_v: |_, _, kv| deserialize_v(kv), From 3e06bee4c622ab460ae1b7be285baa6c756f5353 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 19:47:11 +0100 Subject: [PATCH 12/30] Implement type safe bounds for range_raw --- packages/storage-plus/src/map.rs | 15 ++++++++++++++- packages/storage-plus/src/prefix.rs | 23 +++++++++++++++++++++++ packages/storage-plus/src/snapshot/map.rs | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 7b686ccc4..50be17dab 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -51,7 +51,7 @@ where } #[cfg(feature = "iterator")] - pub(crate) fn no_prefix_raw(&self) -> Prefix, T> { + pub(crate) fn no_prefix_raw(&self) -> Prefix, T, K> { Prefix::new(self.namespace, &[]) } @@ -251,6 +251,19 @@ where T: Serialize + DeserializeOwned, K: PrimaryKey<'a> + KeyDeserialize + Bounder<'a>, { + pub fn range2_raw<'c>( + &self, + store: &'c dyn Storage, + min: Option>, + max: Option>, + order: cosmwasm_std::Order, + ) -> Box>> + 'c> + where + T: 'c, + { + self.no_prefix_raw().range2_raw(store, min, max, order) + } + pub fn range2<'c>( &self, store: &'c dyn Storage, diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 74c97fd52..3adb20420 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -244,6 +244,29 @@ where K: KeyDeserialize, T: Serialize + DeserializeOwned, { + pub fn range2_raw<'a>( + &self, + store: &'a dyn Storage, + min: Option>, + max: Option>, + order: Order, + ) -> Box>> + 'a> + where + T: 'a, + { + let de_fn = self.de_fn_v; + let pk_name = self.pk_name.clone(); + let mapped = range_with_prefix( + store, + &self.storage_prefix, + min.map(|b| b.to_bound()), + max.map(|b| b.to_bound()), + order, + ) + .map(move |kv| (de_fn)(store, &pk_name, kv)); + Box::new(mapped) + } + pub fn range2<'a>( &self, store: &'a dyn Storage, diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 64a042da4..6536099f6 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -73,7 +73,7 @@ where self.primary.key(k) } - fn no_prefix_raw(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T, K> { self.primary.no_prefix_raw() } From 98d01706edb53c1678c02c3be2d7255eec833582 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 19:48:01 +0100 Subject: [PATCH 13/30] Fix: proper trait bounds for Bound2 --- packages/storage-plus/src/prefix.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 3adb20420..cf53e6fd8 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -10,7 +10,7 @@ use crate::de::KeyDeserialize; use crate::helpers::{namespaces_with_key, nested_namespaces_with_key}; use crate::int_key::CwIntKey; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; -use crate::keys::{Bounder, Key}; +use crate::keys::Key; use crate::{Endian, Prefixer, PrimaryKey}; /// Bound is used to defines the two ends of a range, more explicit than Option @@ -51,7 +51,7 @@ pub enum Bound2<'a, K: PrimaryKey<'a>> { Exclusive((K, PhantomData<&'a bool>)), } -impl<'a, K: Bounder<'a>> Bound2<'a, K> { +impl<'a, K: PrimaryKey<'a>> Bound2<'a, K> { pub fn inclusive>(k: T) -> Self { Self::Inclusive((k.into(), PhantomData)) } @@ -240,7 +240,7 @@ where impl<'b, K, T, B> Prefix where - B: Bounder<'b>, + B: PrimaryKey<'b>, K: KeyDeserialize, T: Serialize + DeserializeOwned, { From 8596074d17e15403b5c975a00f217937cf1dc23a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 21:25:11 +0100 Subject: [PATCH 14/30] Rename Bound to RawBound --- contracts/cw1-subkeys/src/contract.rs | 6 +- contracts/cw1155-base/src/contract.rs | 8 +- contracts/cw20-base/src/enumerable.rs | 6 +- contracts/cw3-fixed-multisig/src/contract.rs | 10 +- contracts/cw3-flex-multisig/src/contract.rs | 8 +- contracts/cw4-group/src/contract.rs | 4 +- contracts/cw4-stake/src/contract.rs | 4 +- packages/storage-plus/src/indexed_map.rs | 36 ++++-- packages/storage-plus/src/indexed_snapshot.rs | 20 +-- packages/storage-plus/src/indexes/multi.rs | 18 +-- packages/storage-plus/src/indexes/unique.rs | 18 +-- packages/storage-plus/src/keys.rs | 82 ++++++------- packages/storage-plus/src/lib.rs | 2 +- packages/storage-plus/src/map.rs | 52 ++++---- packages/storage-plus/src/prefix.rs | 116 +++++++++--------- packages/storage-plus/src/snapshot/item.rs | 4 +- packages/storage-plus/src/snapshot/map.rs | 24 ++-- packages/storage-plus/src/snapshot/mod.rs | 6 +- packages/utils/src/pagination.rs | 6 +- 19 files changed, 220 insertions(+), 210 deletions(-) diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index 1d0f2bbb9..e6535ae2f 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -18,7 +18,7 @@ use cw1_whitelist::{ state::ADMIN_LIST, }; use cw2::{get_contract_version, set_contract_version}; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; use cw_utils::Expiration; use semver::Version; @@ -407,7 +407,7 @@ pub fn query_all_allowances( ) -> StdResult { let limit = calc_limit(limit); // we use raw addresses here.... - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let allowances = ALLOWANCES .range(deps.storage, start, None, Order::Ascending) @@ -437,7 +437,7 @@ pub fn query_all_permissions( limit: Option, ) -> StdResult { let limit = calc_limit(limit); - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let permissions = PERMISSIONS .range(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 761b34094..4f254a144 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -3,7 +3,7 @@ use cosmwasm_std::{ to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, SubMsg, Uint128, }; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; use cw1155::{ ApproveAllEvent, ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, @@ -494,7 +494,7 @@ fn query_all_approvals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(|addr| Bound::exclusive(addr.as_ref())); + let start = start_after.map(|addr| RawBound::exclusive(addr.as_ref())); let operators = APPROVES .prefix(&owner) @@ -513,7 +513,7 @@ fn query_tokens( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let tokens = BALANCES .prefix(&owner) @@ -529,7 +529,7 @@ fn query_all_tokens( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let tokens = TOKENS .keys(deps.storage, start, None, Order::Ascending) .take(limit) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index cb7dc74fc..2d165a1d5 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -2,7 +2,7 @@ use cosmwasm_std::{Deps, Order, StdResult}; use cw20::{AllAccountsResponse, AllAllowancesResponse, AllowanceInfo}; use crate::state::{ALLOWANCES, BALANCES}; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; // settings for pagination const MAX_LIMIT: u32 = 30; @@ -16,7 +16,7 @@ pub fn query_all_allowances( ) -> StdResult { let owner_addr = deps.api.addr_validate(&owner)?; let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let allowances = ALLOWANCES .prefix(&owner_addr) @@ -39,7 +39,7 @@ pub fn query_all_accounts( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let accounts = BALANCES .keys(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 394e9bc69..284df3c93 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -12,7 +12,7 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; use cw_utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; @@ -287,7 +287,7 @@ fn list_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive_int); + let start = start_after.map(RawBound::exclusive_int); let proposals = PROPOSALS .range(deps.storage, start, None, Order::Ascending) .take(limit) @@ -304,7 +304,7 @@ fn reverse_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let end = start_before.map(Bound::exclusive_int); + let end = start_before.map(RawBound::exclusive_int); let props: StdResult> = PROPOSALS .range(deps.storage, None, end, Order::Descending) .take(limit) @@ -351,7 +351,7 @@ fn list_votes( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let votes = BALLOTS .prefix(proposal_id) @@ -381,7 +381,7 @@ fn list_voters( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); + let start = start_after.map(RawBound::exclusive); let voters = VOTERS .range(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 929975136..50243ab59 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -14,7 +14,7 @@ use cw3::{ }; use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; @@ -315,7 +315,7 @@ fn list_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive_int); + let start = start_after.map(RawBound::exclusive_int); let proposals = PROPOSALS .range(deps.storage, start, None, Order::Ascending) .take(limit) @@ -332,7 +332,7 @@ fn reverse_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let end = start_before.map(Bound::exclusive_int); + let end = start_before.map(RawBound::exclusive_int); let props: StdResult> = PROPOSALS .range(deps.storage, None, end, Order::Descending) .take(limit) @@ -380,7 +380,7 @@ fn list_votes( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let addr = maybe_addr(deps.api, start_after)?; - let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); + let start = addr.map(|addr| RawBound::exclusive(addr.as_ref())); let votes = BALLOTS .prefix(proposal_id) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index cc3ec20c2..9a7a86cde 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -9,7 +9,7 @@ use cw4::{ Member, MemberChangedHookMsg, MemberDiff, MemberListResponse, MemberResponse, TotalWeightResponse, }; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; use cw_utils::maybe_addr; use crate::error::ContractError; @@ -190,7 +190,7 @@ fn list_members( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let addr = maybe_addr(deps.api, start_after)?; - let start = addr.map(|addr| Bound::exclusive(addr.to_string())); + let start = addr.map(|addr| RawBound::exclusive(addr.to_string())); let members = MEMBERS .range(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index f57be9b9b..28b91ef1a 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -11,7 +11,7 @@ use cw4::{ Member, MemberChangedHookMsg, MemberDiff, MemberListResponse, MemberResponse, TotalWeightResponse, }; -use cw_storage_plus::Bound; +use cw_storage_plus::RawBound; use cw_utils::{maybe_addr, NativeBalance}; use crate::error::ContractError; @@ -339,7 +339,7 @@ fn list_members( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let addr = maybe_addr(deps.api, start_after)?; - let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); + let start = addr.map(|addr| RawBound::exclusive(addr.as_ref())); let members = MEMBERS .range(deps.storage, start, None, Order::Ascending) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index d9a7df53c..e2a6a685c 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -10,7 +10,7 @@ use crate::indexes::Index; use crate::iter_helpers::{deserialize_kv, deserialize_v}; use crate::keys::{Prefixer, PrimaryKey}; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound, RawBound}; use crate::Path; pub trait IndexList { @@ -147,8 +147,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -160,8 +160,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -247,8 +247,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -261,8 +261,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -469,7 +469,12 @@ mod test { let count = map .idx .name - .range_raw(&store, Some(Bound::inclusive(key)), None, Order::Ascending) + .range_raw( + &store, + Some(RawBound::inclusive(key)), + None, + Order::Ascending, + ) .count(); // gets from the first "Maria" until the end assert_eq!(4, count); @@ -484,7 +489,12 @@ mod test { let count = map .idx .name - .range_raw(&store, Some(Bound::exclusive(key)), None, Order::Ascending) + .range_raw( + &store, + Some(RawBound::exclusive(key)), + None, + Order::Ascending, + ) .count(); // gets from the 2nd "Maria" until the end assert_eq!(3, count); @@ -499,7 +509,7 @@ mod test { .age .range_raw( &store, - Some(Bound::inclusive(age_key)), + Some(RawBound::inclusive(age_key)), None, Order::Ascending, ) @@ -1009,7 +1019,7 @@ mod test { let all: StdResult> = map .range( &store, - Some(Bound::Inclusive(b"3".to_vec())), + Some(RawBound::Inclusive(b"3".to_vec())), None, Order::Ascending, ) diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index e5f45bfa2..492d71841 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -8,7 +8,7 @@ use serde::Serialize; use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::keys::{Prefixer, PrimaryKey}; -use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound, RawBound}; use crate::snapshot::{ChangeSet, SnapshotMap}; use crate::{IndexList, Map, Path, Strategy}; @@ -196,8 +196,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -209,8 +209,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -267,8 +267,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -281,8 +281,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -1060,7 +1060,7 @@ mod test { let all: StdResult> = map .range( &store, - Some(Bound::Inclusive(b"3".to_vec())), + Some(RawBound::Inclusive(b"3".to_vec())), None, Order::Ascending, ) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 91a4f29c7..d835e64f5 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -11,7 +11,7 @@ use crate::helpers::namespaces_with_key; use crate::iter_helpers::deserialize_kv; use crate::map::Map; use crate::prefix::{namespaced_prefix_range, PrefixBound}; -use crate::{Bound, Index, Prefix, Prefixer, PrimaryKey}; +use crate::{Index, Prefix, Prefixer, PrimaryKey, RawBound}; use std::marker::PhantomData; /// MultiIndex stores (namespace, index_name, idx_value, pk) -> b"pk_len". @@ -198,8 +198,8 @@ where pub fn range_raw<'c>( &'c self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box>> + 'c> where @@ -211,8 +211,8 @@ where pub fn keys_raw<'c>( &'c self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -304,8 +304,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -318,8 +318,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 6f729db10..6964a09a1 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -12,7 +12,7 @@ use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::map::Map; use crate::prefix::{namespaced_prefix_range, PrefixBound}; -use crate::{Bound, Index, Prefix, Prefixer, PrimaryKey}; +use crate::{Index, Prefix, Prefixer, PrimaryKey, RawBound}; /// UniqueRef stores Binary(Vec[u8]) representation of private key and index value #[derive(Deserialize, Serialize)] @@ -143,8 +143,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box>> + 'c> where @@ -156,8 +156,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -199,8 +199,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -213,8 +213,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index e10e1b02a..b0285194a 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -3,7 +3,7 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::int_key::CwIntKey; -use crate::prefix::Bound2; +use crate::prefix::Bound; #[derive(Debug)] pub enum Key<'a> { @@ -302,25 +302,25 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); pub trait Bounder<'a>: PrimaryKey<'a> + Sized { - fn inclusive_bound(self) -> Option>; - fn exclusive_bound(self) -> Option>; + fn inclusive_bound(self) -> Option>; + fn exclusive_bound(self) -> Option>; } impl<'a> Bounder<'a> for () { - fn inclusive_bound(self) -> Option> { + fn inclusive_bound(self) -> Option> { None } - fn exclusive_bound(self) -> Option> { + fn exclusive_bound(self) -> Option> { None } } impl<'a> Bounder<'a> for &'a [u8] { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } @@ -330,11 +330,11 @@ impl< U: PrimaryKey<'a> + KeyDeserialize + Clone, > Bounder<'a> for (T, U) { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } @@ -345,67 +345,67 @@ impl< V: PrimaryKey<'a> + KeyDeserialize + Clone, > Bounder<'a> for (T, U, V) { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } impl<'a> Bounder<'a> for &'a str { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } impl<'a> Bounder<'a> for String { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } impl<'a> Bounder<'a> for Vec { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } impl<'a> Bounder<'a> for &'a Addr { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } impl<'a> Bounder<'a> for Addr { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } } macro_rules! integer_bound { (for $($t:ty),+) => { $(impl<'a> Bounder<'a> for $t { - fn inclusive_bound(self) -> Option> { - Some(Bound2::inclusive(self)) + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) } - fn exclusive_bound(self) -> Option> { - Some(Bound2::exclusive(self)) + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) } })* } diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index ff8e508b9..35200acff 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -33,6 +33,6 @@ pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] -pub use prefix::{range_with_prefix, Bound, Prefix, PrefixBound}; +pub use prefix::{range_with_prefix, Prefix, PrefixBound, RawBound}; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 50be17dab..67379d893 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -11,9 +11,9 @@ use crate::iter_helpers::{deserialize_kv, deserialize_v}; use crate::keys::Prefixer; use crate::keys::{Bounder, Key, PrimaryKey}; use crate::path::Path; -use crate::prefix::Bound2; +use crate::prefix::Bound; #[cfg(feature = "iterator")] -use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound, RawBound}; use cosmwasm_std::{from_slice, Addr, QuerierWrapper, StdError, StdResult, Storage}; #[derive(Debug, Clone)] @@ -158,8 +158,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -171,8 +171,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -215,8 +215,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -229,8 +229,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -254,8 +254,8 @@ where pub fn range2_raw<'c>( &self, store: &'c dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -267,8 +267,8 @@ where pub fn range2<'c>( &self, store: &'c dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -471,7 +471,7 @@ mod test { let all: StdResult> = PEOPLE .range_raw( &store, - Some(Bound::Inclusive(b"j".to_vec())), + Some(RawBound::Inclusive(b"j".to_vec())), None, Order::Ascending, ) @@ -487,7 +487,7 @@ mod test { let all: StdResult> = PEOPLE .range_raw( &store, - Some(Bound::Inclusive(b"jo".to_vec())), + Some(RawBound::Inclusive(b"jo".to_vec())), None, Order::Ascending, ) @@ -531,7 +531,7 @@ mod test { let all: StdResult> = PEOPLE .range( &store, - Some(Bound::Inclusive(b"j".to_vec())), + Some(RawBound::Inclusive(b"j".to_vec())), None, Order::Ascending, ) @@ -547,7 +547,7 @@ mod test { let all: StdResult> = PEOPLE .range( &store, - Some(Bound::Inclusive(b"jo".to_vec())), + Some(RawBound::Inclusive(b"jo".to_vec())), None, Order::Ascending, ) @@ -646,7 +646,7 @@ mod test { let all: StdResult> = PEOPLE_ID .range( &store, - Some(Bound::inclusive_int(56u32)), + Some(RawBound::inclusive_int(56u32)), None, Order::Ascending, ) @@ -659,7 +659,7 @@ mod test { let all: StdResult> = PEOPLE_ID .range( &store, - Some(Bound::inclusive_int(57u32)), + Some(RawBound::inclusive_int(57u32)), None, Order::Ascending, ) @@ -751,7 +751,7 @@ mod test { let all: StdResult> = SIGNED_ID .range( &store, - Some(Bound::inclusive_int(-56i32)), + Some(RawBound::inclusive_int(-56i32)), None, Order::Ascending, ) @@ -764,8 +764,8 @@ mod test { let all: StdResult> = SIGNED_ID .range( &store, - Some(Bound::inclusive_int(-55i32)), - Some(Bound::inclusive_int(50i32)), + Some(RawBound::inclusive_int(-55i32)), + Some(RawBound::inclusive_int(50i32)), Order::Descending, ) .collect(); @@ -1459,7 +1459,7 @@ mod test { let all: StdResult> = PEOPLE .range_raw( &store, - Some(Bound::Exclusive(b"jim".to_vec())), + Some(RawBound::Exclusive(b"jim".to_vec())), None, Order::Ascending, ) @@ -1486,8 +1486,8 @@ mod test { .prefix(b"owner") .range_raw( &store, - Some(Bound::Exclusive(b"spender1".to_vec())), - Some(Bound::Inclusive(b"spender2".to_vec())), + Some(RawBound::Exclusive(b"spender1".to_vec())), + Some(RawBound::Inclusive(b"spender2".to_vec())), Order::Descending, ) .collect(); diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index cf53e6fd8..d5c1c2b59 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -18,40 +18,40 @@ use crate::{Endian, Prefixer, PrimaryKey}; /// Include means we use the given bytes as a limit and *include* anything at that exact key /// Exclude means we use the given bytes as a limit and *exclude* anything at that exact key #[derive(Clone, Debug)] -pub enum Bound { +pub enum RawBound { Inclusive(Vec), Exclusive(Vec), } -impl Bound { +impl RawBound { /// Turns optional binary, like Option into an inclusive bound pub fn inclusive>>(limit: T) -> Self { - Bound::Inclusive(limit.into()) + RawBound::Inclusive(limit.into()) } /// Turns optional binary, like Option into an exclusive bound pub fn exclusive>>(limit: T) -> Self { - Bound::Exclusive(limit.into()) + RawBound::Exclusive(limit.into()) } /// Turns an int, like Option into an inclusive bound pub fn inclusive_int(limit: T) -> Self { - Bound::Inclusive(limit.to_cw_bytes().into()) + RawBound::Inclusive(limit.to_cw_bytes().into()) } /// Turns an int, like Option into an exclusive bound pub fn exclusive_int(limit: T) -> Self { - Bound::Exclusive(limit.to_cw_bytes().into()) + RawBound::Exclusive(limit.to_cw_bytes().into()) } } #[derive(Clone, Debug)] -pub enum Bound2<'a, K: PrimaryKey<'a>> { +pub enum Bound<'a, K: PrimaryKey<'a>> { Inclusive((K, PhantomData<&'a bool>)), Exclusive((K, PhantomData<&'a bool>)), } -impl<'a, K: PrimaryKey<'a>> Bound2<'a, K> { +impl<'a, K: PrimaryKey<'a>> Bound<'a, K> { pub fn inclusive>(k: T) -> Self { Self::Inclusive((k.into(), PhantomData)) } @@ -60,10 +60,10 @@ impl<'a, K: PrimaryKey<'a>> Bound2<'a, K> { Self::Exclusive((k.into(), PhantomData)) } - pub fn to_bound(&self) -> Bound { + pub fn to_raw_bound(&self) -> RawBound { match self { - Bound2::Exclusive((k, _)) => Bound::Exclusive(k.joined_key()), - Bound2::Inclusive((k, _)) => Bound::Inclusive(k.joined_key()), + Bound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_key()), + Bound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_key()), } } } @@ -83,10 +83,10 @@ impl<'a, K: Prefixer<'a>> PrefixBound<'a, K> { Self::Exclusive((k.into(), PhantomData)) } - pub fn to_bound(&self) -> Bound { + pub fn to_raw_bound(&self) -> RawBound { match self { - PrefixBound::Exclusive((k, _)) => Bound::Exclusive(k.joined_prefix()), - PrefixBound::Inclusive((k, _)) => Bound::Inclusive(k.joined_prefix()), + PrefixBound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_prefix()), + PrefixBound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_prefix()), } } } @@ -174,8 +174,8 @@ where pub fn range_raw<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box>> + 'a> where @@ -191,8 +191,8 @@ where pub fn keys_raw<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box> + 'a> { let mapped = @@ -203,8 +203,8 @@ where pub fn range<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box> + 'a> where @@ -221,8 +221,8 @@ where pub fn keys<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: Order, ) -> Box> + 'a> where @@ -247,8 +247,8 @@ where pub fn range2_raw<'a>( &self, store: &'a dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: Order, ) -> Box>> + 'a> where @@ -259,8 +259,8 @@ where let mapped = range_with_prefix( store, &self.storage_prefix, - min.map(|b| b.to_bound()), - max.map(|b| b.to_bound()), + min.map(|b| b.to_raw_bound()), + max.map(|b| b.to_raw_bound()), order, ) .map(move |kv| (de_fn)(store, &pk_name, kv)); @@ -270,8 +270,8 @@ where pub fn range2<'a>( &self, store: &'a dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'a> where @@ -283,8 +283,8 @@ where let mapped = range_with_prefix( store, &self.storage_prefix, - min.map(|b| b.to_bound()), - max.map(|b| b.to_bound()), + min.map(|b| b.to_raw_bound()), + max.map(|b| b.to_raw_bound()), order, ) .map(move |kv| (de_fn)(store, &pk_name, kv)); @@ -295,8 +295,8 @@ where pub fn range_with_prefix<'a>( storage: &'a dyn Storage, namespace: &[u8], - start: Option, - end: Option, + start: Option, + end: Option, order: Order, ) -> Box + 'a> { let start = calc_start_bound(namespace, start); @@ -311,21 +311,21 @@ pub fn range_with_prefix<'a>( Box::new(mapped) } -fn calc_start_bound(namespace: &[u8], bound: Option) -> Vec { +fn calc_start_bound(namespace: &[u8], bound: Option) -> Vec { match bound { None => namespace.to_vec(), // this is the natural limits of the underlying Storage - Some(Bound::Inclusive(limit)) => concat(namespace, &limit), - Some(Bound::Exclusive(limit)) => concat(namespace, &extend_one_byte(&limit)), + Some(RawBound::Inclusive(limit)) => concat(namespace, &limit), + Some(RawBound::Exclusive(limit)) => concat(namespace, &extend_one_byte(&limit)), } } -fn calc_end_bound(namespace: &[u8], bound: Option) -> Vec { +fn calc_end_bound(namespace: &[u8], bound: Option) -> Vec { match bound { None => increment_last_byte(namespace), // this is the natural limits of the underlying Storage - Some(Bound::Exclusive(limit)) => concat(namespace, &limit), - Some(Bound::Inclusive(limit)) => concat(namespace, &extend_one_byte(&limit)), + Some(RawBound::Exclusive(limit)) => concat(namespace, &limit), + Some(RawBound::Inclusive(limit)) => concat(namespace, &extend_one_byte(&limit)), } } @@ -352,11 +352,11 @@ fn calc_prefix_start_bound<'a, K: Prefixer<'a>>( namespace: &[u8], bound: Option>, ) -> Vec { - match bound.map(|b| b.to_bound()) { + match bound.map(|b| b.to_raw_bound()) { None => namespace.to_vec(), // this is the natural limits of the underlying Storage - Some(Bound::Inclusive(limit)) => concat(namespace, &limit), - Some(Bound::Exclusive(limit)) => concat(namespace, &increment_last_byte(&limit)), + Some(RawBound::Inclusive(limit)) => concat(namespace, &limit), + Some(RawBound::Exclusive(limit)) => concat(namespace, &increment_last_byte(&limit)), } } @@ -364,11 +364,11 @@ fn calc_prefix_end_bound<'a, K: Prefixer<'a>>( namespace: &[u8], bound: Option>, ) -> Vec { - match bound.map(|b| b.to_bound()) { + match bound.map(|b| b.to_raw_bound()) { None => increment_last_byte(namespace), // this is the natural limits of the underlying Storage - Some(Bound::Exclusive(limit)) => concat(namespace, &limit), - Some(Bound::Inclusive(limit)) => concat(namespace, &increment_last_byte(&limit)), + Some(RawBound::Exclusive(limit)) => concat(namespace, &limit), + Some(RawBound::Inclusive(limit)) => concat(namespace, &increment_last_byte(&limit)), } } @@ -441,7 +441,7 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Inclusive(b"ra".to_vec())), + Some(RawBound::Inclusive(b"ra".to_vec())), None, Order::Ascending, ) @@ -451,7 +451,7 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Exclusive(b"ra".to_vec())), + Some(RawBound::Exclusive(b"ra".to_vec())), None, Order::Ascending, ) @@ -461,7 +461,7 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Exclusive(b"r".to_vec())), + Some(RawBound::Exclusive(b"r".to_vec())), None, Order::Ascending, ) @@ -473,7 +473,7 @@ mod test { .range_raw( &store, None, - Some(Bound::Inclusive(b"ra".to_vec())), + Some(RawBound::Inclusive(b"ra".to_vec())), Order::Descending, ) .collect(); @@ -483,7 +483,7 @@ mod test { .range_raw( &store, None, - Some(Bound::Exclusive(b"ra".to_vec())), + Some(RawBound::Exclusive(b"ra".to_vec())), Order::Descending, ) .collect(); @@ -493,7 +493,7 @@ mod test { .range_raw( &store, None, - Some(Bound::Exclusive(b"rb".to_vec())), + Some(RawBound::Exclusive(b"rb".to_vec())), Order::Descending, ) .collect(); @@ -503,8 +503,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Inclusive(b"ra".to_vec())), - Some(Bound::Exclusive(b"zi".to_vec())), + Some(RawBound::Inclusive(b"ra".to_vec())), + Some(RawBound::Exclusive(b"zi".to_vec())), Order::Ascending, ) .collect(); @@ -513,8 +513,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Inclusive(b"ra".to_vec())), - Some(Bound::Exclusive(b"zi".to_vec())), + Some(RawBound::Inclusive(b"ra".to_vec())), + Some(RawBound::Exclusive(b"zi".to_vec())), Order::Descending, ) .collect(); @@ -523,8 +523,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Inclusive(b"ra".to_vec())), - Some(Bound::Inclusive(b"zi".to_vec())), + Some(RawBound::Inclusive(b"ra".to_vec())), + Some(RawBound::Inclusive(b"zi".to_vec())), Order::Descending, ) .collect(); @@ -533,8 +533,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(Bound::Exclusive(b"ra".to_vec())), - Some(Bound::Exclusive(b"zi".to_vec())), + Some(RawBound::Exclusive(b"ra".to_vec())), + Some(RawBound::Exclusive(b"zi".to_vec())), Order::Ascending, ) .collect(); diff --git a/packages/storage-plus/src/snapshot/item.rs b/packages/storage-plus/src/snapshot/item.rs index 3cf9bfa0a..1fe58c332 100644 --- a/packages/storage-plus/src/snapshot/item.rs +++ b/packages/storage-plus/src/snapshot/item.rs @@ -283,7 +283,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] fn changelog_range_works() { - use crate::Bound; + use crate::RawBound; use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -318,7 +318,7 @@ mod tests { .changelog() .range( &store, - Some(Bound::exclusive_int(3u64)), + Some(RawBound::exclusive_int(3u64)), None, Order::Ascending, ) diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 6536099f6..d52713fa5 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -10,7 +10,7 @@ use crate::map::Map; use crate::path::Path; use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound}; use crate::snapshot::{ChangeSet, Snapshot}; -use crate::{Bound, Prefixer, Strategy}; +use crate::{Prefixer, RawBound, Strategy}; /// Map that maintains a snapshots of one or more checkpoints. /// We can query historical data as well as current state. @@ -171,8 +171,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -184,8 +184,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -228,8 +228,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -242,8 +242,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -516,7 +516,7 @@ mod tests { .prefix("A") .range( &store, - Some(Bound::inclusive_int(3u64)), + Some(RawBound::inclusive_int(3u64)), None, Order::Ascending, ) @@ -544,7 +544,7 @@ mod tests { let all: StdResult> = EVERY .range( &store, - Some(Bound::Inclusive(b"C".to_vec())), + Some(RawBound::Inclusive(b"C".to_vec())), None, Order::Ascending, ) @@ -557,7 +557,7 @@ mod tests { let all: StdResult> = EVERY .range( &store, - Some(Bound::Inclusive(b"D".to_vec())), + Some(RawBound::Inclusive(b"D".to_vec())), None, Order::Ascending, ) diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index 889f1fad6..9caf904d3 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -6,7 +6,7 @@ pub use item::SnapshotItem; pub use map::SnapshotMap; use crate::de::KeyDeserialize; -use crate::{Bound, Map, Prefixer, PrimaryKey}; +use crate::{Map, Prefixer, PrimaryKey, RawBound}; use cosmwasm_std::{Order, StdError, StdResult, Storage}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -84,7 +84,7 @@ where .transpose()?; if let Some((height, _)) = checkpoint { // any changelog for the given key since then? - let start = Bound::inclusive(height); + let start = RawBound::inclusive(height); let first = self .changelog .prefix(k.clone()) @@ -143,7 +143,7 @@ where // this will look for the first snapshot of height >= given height // If None, there is no snapshot since that time. - let start = Bound::inclusive_int(height); + let start = RawBound::inclusive_int(height); let first = self .changelog .prefix(key) diff --git a/packages/utils/src/pagination.rs b/packages/utils/src/pagination.rs index 7af917acd..ba6e825a1 100644 --- a/packages/utils/src/pagination.rs +++ b/packages/utils/src/pagination.rs @@ -37,7 +37,7 @@ pub fn calc_range_start_string(start_after: Option) -> Option> { mod test { use super::*; use cosmwasm_std::{testing::mock_dependencies, Order}; - use cw_storage_plus::{Bound, Map}; + use cw_storage_plus::{RawBound, Map}; pub const HOLDERS: Map<&Addr, usize> = Map::new("some_data"); const LIMIT: usize = 30; @@ -64,7 +64,7 @@ mod test { Some(addr_from_i(j * LIMIT - 1)) }; - let start = calc_range_start(start_after).map(Bound::exclusive); + let start = calc_range_start(start_after).map(RawBound::exclusive); let holders = HOLDERS .keys(&deps.storage, start, None, Order::Ascending) @@ -93,7 +93,7 @@ mod test { for j in 0..4 { let end_before = Some(addr_from_i(total_elements_count - j * LIMIT)); - let end = calc_range_end(end_before).map(Bound::exclusive); + let end = calc_range_end(end_before).map(RawBound::exclusive); let holders = HOLDERS .keys(&deps.storage, None, end, Order::Descending) From bafe270f9e4b5d0cd7e0dbd899e229419a40d7dd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 8 Jan 2022 21:28:52 +0100 Subject: [PATCH 15/30] Adjust doc comments --- packages/storage-plus/src/prefix.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index d5c1c2b59..9a40fd402 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -13,10 +13,11 @@ use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; use crate::keys::Key; use crate::{Endian, Prefixer, PrimaryKey}; -/// Bound is used to defines the two ends of a range, more explicit than Option -/// None means that we don't limit that side of the range at all. -/// Include means we use the given bytes as a limit and *include* anything at that exact key -/// Exclude means we use the given bytes as a limit and *exclude* anything at that exact key +/// `RawBound` is used to define the two ends of a range, more explicit than `Option`. +/// `None` means that we don't limit that side of the range at all. +/// `Inclusive` means we use the given bytes as a limit and *include* anything at that exact key. +/// `Exclusive` means we use the given bytes as a limit and *exclude* anything at that exact key. +/// See `Bound` for a type safe way to build these bounds. #[derive(Clone, Debug)] pub enum RawBound { Inclusive(Vec), @@ -45,6 +46,10 @@ impl RawBound { } } +/// `Bound` is used to define the two ends of a range. +/// `None` means that we don't limit that side of the range at all. +/// `Inclusive` means we use the given value as a limit and *include* anything at that exact key. +/// `Exclusive` means we use the given value as a limit and *exclude* anything at that exact key. #[derive(Clone, Debug)] pub enum Bound<'a, K: PrimaryKey<'a>> { Inclusive((K, PhantomData<&'a bool>)), From 7a44f45e3959cb0255c03ff46eceefc17077889b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 09:36:33 +0100 Subject: [PATCH 16/30] Replace RawBound by Bound --- packages/storage-plus/src/indexed_map.rs | 70 +++++----- packages/storage-plus/src/indexed_snapshot.rs | 22 +-- packages/storage-plus/src/indexes/multi.rs | 24 ++-- packages/storage-plus/src/indexes/unique.rs | 28 ++-- packages/storage-plus/src/map.rs | 125 +++++++----------- packages/storage-plus/src/prefix.rs | 89 +++++-------- packages/storage-plus/src/snapshot/map.rs | 26 ++-- packages/storage-plus/src/snapshot/mod.rs | 9 +- 8 files changed, 165 insertions(+), 228 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index e2a6a685c..2057329dc 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -10,7 +10,7 @@ use crate::indexes::Index; use crate::iter_helpers::{deserialize_kv, deserialize_v}; use crate::keys::{Prefixer, PrimaryKey}; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound, RawBound}; +use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; use crate::Path; pub trait IndexList { @@ -130,44 +130,11 @@ where } // use no_prefix to scan -> range - fn no_prefix_raw(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T, K> { Prefix::new(self.pk_namespace, &[]) } } -// short-cut for simple keys, rather than .prefix(()).range_raw(...) -impl<'a, K, T, I> IndexedMap<'a, K, T, I> -where - K: PrimaryKey<'a>, - T: Serialize + DeserializeOwned + Clone, - I: IndexList, -{ - // I would prefer not to copy code from Prefix, but no other way - // with lifetimes (create Prefix inside function and return ref = no no) - pub fn range_raw<'c>( - &self, - store: &'c dyn Storage, - min: Option, - max: Option, - order: cosmwasm_std::Order, - ) -> Box>> + 'c> - where - T: 'c, - { - self.no_prefix_raw().range_raw(store, min, max, order) - } - - pub fn keys_raw<'c>( - &self, - store: &'c dyn Storage, - min: Option, - max: Option, - order: cosmwasm_std::Order, - ) -> Box> + 'c> { - self.no_prefix_raw().keys_raw(store, min, max, order) - } -} - #[cfg(feature = "iterator")] impl<'a, K, T, I> IndexedMap<'a, K, T, I> where @@ -244,11 +211,34 @@ where Box::new(mapped) } + pub fn range_raw<'c>( + &self, + store: &'c dyn Storage, + min: Option>, + max: Option>, + order: cosmwasm_std::Order, + ) -> Box>> + 'c> + where + T: 'c, + { + self.no_prefix_raw().range_raw(store, min, max, order) + } + + pub fn keys_raw<'c>( + &self, + store: &'c dyn Storage, + min: Option>, + max: Option>, + order: cosmwasm_std::Order, + ) -> Box> + 'c> { + self.no_prefix_raw().keys_raw(store, min, max, order) + } + pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -261,8 +251,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -272,7 +262,7 @@ where self.no_prefix().keys(store, min, max, order) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.pk_namespace, &[]) } } diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 492d71841..ea305f5d9 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -8,7 +8,7 @@ use serde::Serialize; use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::keys::{Prefixer, PrimaryKey}; -use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound, RawBound}; +use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; use crate::snapshot::{ChangeSet, SnapshotMap}; use crate::{IndexList, Map, Path, Strategy}; @@ -179,7 +179,7 @@ where } // use no_prefix to scan -> range - pub fn no_prefix_raw(&self) -> Prefix, T> { + pub fn no_prefix_raw(&self) -> Prefix, T, K> { Prefix::new(self.pk_namespace, &[]) } } @@ -196,8 +196,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -209,8 +209,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -267,8 +267,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -281,8 +281,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -292,7 +292,7 @@ where self.no_prefix().keys(store, min, max, order) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.pk_namespace, &[]) } } diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index d835e64f5..3ea4c6bbb 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -10,8 +10,8 @@ use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::iter_helpers::deserialize_kv; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, PrefixBound}; -use crate::{Index, Prefix, Prefixer, PrimaryKey, RawBound}; +use crate::prefix::{namespaced_prefix_range, Bound, PrefixBound}; +use crate::{Index, Prefix, Prefixer, PrimaryKey}; use std::marker::PhantomData; /// MultiIndex stores (namespace, index_name, idx_value, pk) -> b"pk_len". @@ -143,7 +143,7 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + Prefixer<'a>, { - fn no_prefix_raw(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T, IK> { Prefix::with_deserialization_functions( self.idx_namespace, &[], @@ -198,8 +198,8 @@ where pub fn range_raw<'c>( &'c self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box>> + 'c> where @@ -211,8 +211,8 @@ where pub fn keys_raw<'c>( &'c self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -304,8 +304,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -318,8 +318,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -329,7 +329,7 @@ where self.no_prefix().keys(store, min, max, order) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &[], diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 6964a09a1..9200ce552 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -11,8 +11,8 @@ use cosmwasm_std::{from_slice, Binary, Order, Record, StdError, StdResult, Stora use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, PrefixBound}; -use crate::{Index, Prefix, Prefixer, PrimaryKey, RawBound}; +use crate::prefix::{namespaced_prefix_range, Bound, PrefixBound}; +use crate::{Index, Prefix, Prefixer, PrimaryKey}; /// UniqueRef stores Binary(Vec[u8]) representation of private key and index value #[derive(Deserialize, Serialize)] @@ -112,7 +112,7 @@ where k.joined_key() } - fn no_prefix_raw(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T, IK> { Prefix::with_deserialization_functions( self.idx_namespace, &[], @@ -143,8 +143,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box>> + 'c> where @@ -156,8 +156,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -199,8 +199,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -213,8 +213,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -224,7 +224,7 @@ where self.no_prefix().keys(store, min, max, order) } - pub fn prefix(&self, p: IK::Prefix) -> Prefix { + pub fn prefix(&self, p: IK::Prefix) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), @@ -234,7 +234,7 @@ where ) } - pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), @@ -244,7 +244,7 @@ where ) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &[], diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 67379d893..6e83fabaa 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -13,7 +13,7 @@ use crate::keys::{Bounder, Key, PrimaryKey}; use crate::path::Path; use crate::prefix::Bound; #[cfg(feature = "iterator")] -use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound, RawBound}; +use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound}; use cosmwasm_std::{from_slice, Addr, QuerierWrapper, StdError, StdResult, Storage}; #[derive(Debug, Clone)] @@ -154,32 +154,6 @@ where namespaced_prefix_range(store, self.namespace, min, max, order).map(deserialize_v); Box::new(mapped) } - - pub fn range_raw<'c>( - &self, - store: &'c dyn Storage, - min: Option, - max: Option, - order: cosmwasm_std::Order, - ) -> Box>> + 'c> - where - T: 'c, - { - self.no_prefix_raw().range_raw(store, min, max, order) - } - - pub fn keys_raw<'c>( - &self, - store: &'c dyn Storage, - min: Option, - max: Option, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - { - self.no_prefix_raw().keys_raw(store, min, max, order) - } } #[cfg(feature = "iterator")] @@ -212,70 +186,69 @@ where Box::new(mapped) } - pub fn range<'c>( + fn no_prefix(&self) -> Prefix { + Prefix::new(self.namespace, &[]) + } +} + +#[cfg(feature = "iterator")] +impl<'a, K, T> Map<'a, K, T> +where + T: Serialize + DeserializeOwned, + K: PrimaryKey<'a> + KeyDeserialize + Bounder<'a>, +{ + pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, - ) -> Box> + 'c> + ) -> Box>> + 'c> where T: 'c, - K::Output: 'static, { - self.no_prefix().range(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } - pub fn keys<'c>( + pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, - ) -> Box> + 'c> + ) -> Box> + 'c> where T: 'c, - K::Output: 'static, { - self.no_prefix().keys(store, min, max, order) - } - - fn no_prefix(&self) -> Prefix { - Prefix::new(self.namespace, &[]) + self.no_prefix_raw().keys_raw(store, min, max, order) } -} -#[cfg(feature = "iterator")] -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + KeyDeserialize + Bounder<'a>, -{ - pub fn range2_raw<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option>, max: Option>, order: cosmwasm_std::Order, - ) -> Box>> + 'c> + ) -> Box> + 'c> where T: 'c, + K::Output: 'static, { - self.no_prefix_raw().range2_raw(store, min, max, order) + self.no_prefix().range(store, min, max, order) } - pub fn range2<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option>, max: Option>, order: cosmwasm_std::Order, - ) -> Box> + 'c> + ) -> Box> + 'c> where T: 'c, K::Output: 'static, { - self.no_prefix().range2(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } } @@ -582,9 +555,7 @@ mod test { PEOPLE.save(&mut store, b"ada", &data3).unwrap(); // let's try to iterate! - let all: StdResult> = PEOPLE - .range2(&store, None, None, Order::Ascending) - .collect(); + let all: StdResult> = PEOPLE.range(&store, None, None, Order::Ascending).collect(); let all = all.unwrap(); assert_eq!(3, all.len()); assert_eq!( @@ -598,7 +569,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = PEOPLE - .range2(&store, b"j".inclusive_bound(), None, Order::Ascending) + .range(&store, b"j".inclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -609,7 +580,7 @@ mod test { // let's try to iterate over a more restrictive range let all: StdResult> = PEOPLE - .range2(&store, b"jo".inclusive_bound(), None, Order::Ascending) + .range(&store, b"jo".inclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); @@ -688,7 +659,7 @@ mod test { // let's try to iterate! let all: StdResult> = PEOPLE_ID - .range2(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -696,7 +667,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = PEOPLE_ID - .range2(&store, 56u32.inclusive_bound(), None, Order::Ascending) + .range(&store, 56u32.inclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -704,7 +675,7 @@ mod test { // let's try to iterate over a more restrictive range let all: StdResult> = PEOPLE_ID - .range2(&store, 57u32.inclusive_bound(), None, Order::Ascending) + .range(&store, 57u32.inclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); @@ -800,7 +771,7 @@ mod test { // let's try to iterate! let all: StdResult> = SIGNED_ID - .range2(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); @@ -812,7 +783,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = SIGNED_ID - .range2(&store, (-56i32).inclusive_bound(), None, Order::Ascending) + .range(&store, (-56i32).inclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -820,7 +791,7 @@ mod test { // let's try to iterate over a more restrictive range let all: StdResult> = SIGNED_ID - .range2( + .range( &store, (-55i32).inclusive_bound(), 50i32.inclusive_bound(), @@ -1008,7 +979,7 @@ mod test { // let's try to iterate! let all: StdResult> = ALLOWANCE - .range2(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); @@ -1024,7 +995,7 @@ mod test { // let's try to iterate over a prefix let all: StdResult> = ALLOWANCE .prefix(b"owner") - .range2(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -1036,7 +1007,7 @@ mod test { // let's try to iterate over a prefixed restricted inclusive range let all: StdResult> = ALLOWANCE .prefix(b"owner") - .range2(&store, b"spender".inclusive_bound(), None, Order::Ascending) + .range(&store, b"spender".inclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -1048,7 +1019,7 @@ mod test { // let's try to iterate over a prefixed restricted exclusive range let all: StdResult> = ALLOWANCE .prefix(b"owner") - .range2(&store, b"spender".exclusive_bound(), None, Order::Ascending) + .range(&store, b"spender".exclusive_bound(), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); @@ -1220,9 +1191,7 @@ mod test { .unwrap(); // let's try to iterate! - let all: StdResult> = TRIPLE - .range2(&store, None, None, Order::Ascending) - .collect(); + let all: StdResult> = TRIPLE.range(&store, None, None, Order::Ascending).collect(); let all = all.unwrap(); assert_eq!(4, all.len()); assert_eq!( @@ -1238,7 +1207,7 @@ mod test { // let's iterate over a sub_prefix let all: StdResult> = TRIPLE .sub_prefix(b"owner") - .range2(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); @@ -1254,7 +1223,7 @@ mod test { // let's iterate over a prefix let all: StdResult> = TRIPLE .prefix((b"owner", 9)) - .range2(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -1269,7 +1238,7 @@ mod test { // let's try to iterate over a prefixed restricted inclusive range let all: StdResult> = TRIPLE .prefix((b"owner", 9)) - .range2( + .range( &store, "recipient".inclusive_bound(), None, @@ -1289,7 +1258,7 @@ mod test { // let's try to iterate over a prefixed restricted exclusive range let all: StdResult> = TRIPLE .prefix((b"owner", 9)) - .range2( + .range( &store, "recipient".exclusive_bound(), None, diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 9a40fd402..8c5180ef9 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -175,12 +175,19 @@ where de_fn_v, } } +} +impl<'b, K, T, B> Prefix +where + B: PrimaryKey<'b>, + K: KeyDeserialize, + T: Serialize + DeserializeOwned, +{ pub fn range_raw<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box>> + 'a> where @@ -188,28 +195,40 @@ where { let de_fn = self.de_fn_v; let pk_name = self.pk_name.clone(); - let mapped = range_with_prefix(store, &self.storage_prefix, min, max, order) - .map(move |kv| (de_fn)(store, &pk_name, kv)); + let mapped = range_with_prefix( + store, + &self.storage_prefix, + min.map(|b| b.to_raw_bound()), + max.map(|b| b.to_raw_bound()), + order, + ) + .map(move |kv| (de_fn)(store, &pk_name, kv)); Box::new(mapped) } pub fn keys_raw<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'a> { - let mapped = - range_with_prefix(store, &self.storage_prefix, min, max, order).map(|(k, _)| k); + let mapped = range_with_prefix( + store, + &self.storage_prefix, + min.map(|b| b.to_raw_bound()), + max.map(|b| b.to_raw_bound()), + order, + ) + .map(|(k, _)| k); Box::new(mapped) } pub fn range<'a>( &self, store: &'a dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'a> where @@ -218,49 +237,6 @@ where { let de_fn = self.de_fn_kv; let pk_name = self.pk_name.clone(); - let mapped = range_with_prefix(store, &self.storage_prefix, min, max, order) - .map(move |kv| (de_fn)(store, &pk_name, kv)); - Box::new(mapped) - } - - pub fn keys<'a>( - &self, - store: &'a dyn Storage, - min: Option, - max: Option, - order: Order, - ) -> Box> + 'a> - where - T: 'a, - K::Output: 'static, - { - let de_fn = self.de_fn_kv; - let pk_name = self.pk_name.clone(); - let mapped = range_with_prefix(store, &self.storage_prefix, min, max, order) - .map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| Ok(k))) - .flatten(); - Box::new(mapped) - } -} - -impl<'b, K, T, B> Prefix -where - B: PrimaryKey<'b>, - K: KeyDeserialize, - T: Serialize + DeserializeOwned, -{ - pub fn range2_raw<'a>( - &self, - store: &'a dyn Storage, - min: Option>, - max: Option>, - order: Order, - ) -> Box>> + 'a> - where - T: 'a, - { - let de_fn = self.de_fn_v; - let pk_name = self.pk_name.clone(); let mapped = range_with_prefix( store, &self.storage_prefix, @@ -272,13 +248,13 @@ where Box::new(mapped) } - pub fn range2<'a>( + pub fn keys<'a>( &self, store: &'a dyn Storage, min: Option>, max: Option>, order: Order, - ) -> Box> + 'a> + ) -> Box> + 'a> where T: 'a, K::Output: 'static, @@ -292,7 +268,8 @@ where max.map(|b| b.to_raw_bound()), order, ) - .map(move |kv| (de_fn)(store, &pk_name, kv)); + .map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| Ok(k))) + .flatten(); Box::new(mapped) } } diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index d52713fa5..db142e4a8 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -8,9 +8,9 @@ use crate::iter_helpers::deserialize_kv; use crate::keys::PrimaryKey; use crate::map::Map; use crate::path::Path; -use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; use crate::snapshot::{ChangeSet, Snapshot}; -use crate::{Prefixer, RawBound, Strategy}; +use crate::{Prefixer, Strategy}; /// Map that maintains a snapshots of one or more checkpoints. /// We can query historical data as well as current state. @@ -171,8 +171,8 @@ where pub fn range_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -184,8 +184,8 @@ where pub fn keys_raw<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -228,8 +228,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -242,8 +242,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option, - max: Option, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -253,15 +253,15 @@ where self.no_prefix().keys(store, min, max, order) } - pub fn prefix(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.primary.namespace(), &p.prefix()) } - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.primary.namespace(), &p.prefix()) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.primary.namespace(), &[]) } } diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index 9caf904d3..bf2436c9e 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -6,7 +6,8 @@ pub use item::SnapshotItem; pub use map::SnapshotMap; use crate::de::KeyDeserialize; -use crate::{Map, Prefixer, PrimaryKey, RawBound}; +use crate::prefix::Bound; +use crate::{Map, Prefixer, PrimaryKey}; use cosmwasm_std::{Order, StdError, StdResult, Storage}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -79,12 +80,12 @@ where // most recent checkpoint let checkpoint = self .checkpoints - .range_raw(store, None, None, Order::Descending) + .range(store, None, None, Order::Descending) .next() .transpose()?; if let Some((height, _)) = checkpoint { // any changelog for the given key since then? - let start = RawBound::inclusive(height); + let start = Bound::inclusive(height); let first = self .changelog .prefix(k.clone()) @@ -143,7 +144,7 @@ where // this will look for the first snapshot of height >= given height // If None, there is no snapshot since that time. - let start = RawBound::inclusive_int(height); + let start = Bound::inclusive(height); let first = self .changelog .prefix(key) From 7e88c48fa3a6d75e2009ff4a056d2a9e039ccad5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 10:54:06 +0100 Subject: [PATCH 17/30] Replace RawBound by Bound in tests --- packages/storage-plus/src/indexed_map.rs | 15 +++----- packages/storage-plus/src/indexed_snapshot.rs | 7 +--- packages/storage-plus/src/map.rs | 32 +++++++++-------- packages/storage-plus/src/prefix.rs | 34 +++++++++++-------- packages/storage-plus/src/snapshot/item.rs | 9 ++--- packages/storage-plus/src/snapshot/map.rs | 21 ++---------- 6 files changed, 46 insertions(+), 72 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 2057329dc..67ab57652 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -461,7 +461,7 @@ mod test { .name .range_raw( &store, - Some(RawBound::inclusive(key)), + Some(Bound::InclusiveRaw(key)), None, Order::Ascending, ) @@ -481,7 +481,7 @@ mod test { .name .range_raw( &store, - Some(RawBound::exclusive(key)), + Some(Bound::ExclusiveRaw(key)), None, Order::Ascending, ) @@ -491,15 +491,13 @@ mod test { // index_key() over UniqueIndex works. let age_key = 23u32; - // Use the index_key() helper to build the (raw) index key - let age_key = map.idx.age.index_key(age_key); // Iterate using a (inclusive) bound over the raw key. let count = map .idx .age .range_raw( &store, - Some(RawBound::inclusive(age_key)), + Some(Bound::inclusive(age_key)), None, Order::Ascending, ) @@ -1007,12 +1005,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = map - .range( - &store, - Some(RawBound::Inclusive(b"3".to_vec())), - None, - Order::Ascending, - ) + .range(&store, Some(Bound::inclusive("3")), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!( diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index ea305f5d9..f15297506 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -1058,12 +1058,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = map - .range( - &store, - Some(RawBound::Inclusive(b"3".to_vec())), - None, - Order::Ascending, - ) + .range(&store, Some(Bound::inclusive("3")), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!( diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 6e83fabaa..6ebe57da7 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -263,7 +263,7 @@ mod test { use cosmwasm_std::{Order, StdResult}; use crate::int_key::CwIntKey; - use crate::keys_old::IntKeyOld; + // use crate::keys_old::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { @@ -274,8 +274,8 @@ mod test { const PEOPLE: Map<&[u8], Data> = Map::new("people"); #[cfg(feature = "iterator")] const PEOPLE_ID: Map = Map::new("people_id"); - #[cfg(feature = "iterator")] - const SIGNED_ID_OLD: Map, Data> = Map::new("signed_id"); + // #[cfg(feature = "iterator")] + // const SIGNED_ID_OLD: Map, Data> = Map::new("signed_id"); #[cfg(feature = "iterator")] const SIGNED_ID: Map = Map::new("signed_id"); @@ -444,7 +444,7 @@ mod test { let all: StdResult> = PEOPLE .range_raw( &store, - Some(RawBound::Inclusive(b"j".to_vec())), + Some(Bound::inclusive(b"j" as &[u8])), None, Order::Ascending, ) @@ -460,7 +460,7 @@ mod test { let all: StdResult> = PEOPLE .range_raw( &store, - Some(RawBound::Inclusive(b"jo".to_vec())), + Some(Bound::inclusive(b"jo" as &[u8])), None, Order::Ascending, ) @@ -504,7 +504,7 @@ mod test { let all: StdResult> = PEOPLE .range( &store, - Some(RawBound::Inclusive(b"j".to_vec())), + Some(Bound::inclusive(b"j" as &[u8])), None, Order::Ascending, ) @@ -520,7 +520,7 @@ mod test { let all: StdResult> = PEOPLE .range( &store, - Some(RawBound::Inclusive(b"jo".to_vec())), + Some(Bound::inclusive(b"jo" as &[u8])), None, Order::Ascending, ) @@ -617,7 +617,7 @@ mod test { let all: StdResult> = PEOPLE_ID .range( &store, - Some(RawBound::inclusive_int(56u32)), + Some(Bound::inclusive(56u32)), None, Order::Ascending, ) @@ -630,7 +630,7 @@ mod test { let all: StdResult> = PEOPLE_ID .range( &store, - Some(RawBound::inclusive_int(57u32)), + Some(Bound::inclusive(57u32)), None, Order::Ascending, ) @@ -722,7 +722,7 @@ mod test { let all: StdResult> = SIGNED_ID .range( &store, - Some(RawBound::inclusive_int(-56i32)), + Some(Bound::inclusive(-56i32)), None, Order::Ascending, ) @@ -735,8 +735,8 @@ mod test { let all: StdResult> = SIGNED_ID .range( &store, - Some(RawBound::inclusive_int(-55i32)), - Some(RawBound::inclusive_int(50i32)), + Some(Bound::inclusive(-55i32)), + Some(Bound::inclusive(50i32)), Order::Descending, ) .collect(); @@ -803,6 +803,7 @@ mod test { assert_eq!(all, vec![(50, data3)]); } + /* #[test] #[cfg(feature = "iterator")] fn range_signed_integer_key_migration() { @@ -872,6 +873,7 @@ mod test { // confirm new order is right assert_eq!(new, vec![(-1234, data), (-56, data2), (50, data3)]); } + */ #[test] #[cfg(feature = "iterator")] @@ -1428,7 +1430,7 @@ mod test { let all: StdResult> = PEOPLE .range_raw( &store, - Some(RawBound::Exclusive(b"jim".to_vec())), + Some(Bound::exclusive(b"jim" as &[u8])), None, Order::Ascending, ) @@ -1455,8 +1457,8 @@ mod test { .prefix(b"owner") .range_raw( &store, - Some(RawBound::Exclusive(b"spender1".to_vec())), - Some(RawBound::Inclusive(b"spender2".to_vec())), + Some(Bound::exclusive(b"spender1" as &[u8])), + Some(Bound::inclusive(b"spender2" as &[u8])), Order::Descending, ) .collect(); diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 8c5180ef9..01edfbb34 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -54,6 +54,8 @@ impl RawBound { pub enum Bound<'a, K: PrimaryKey<'a>> { Inclusive((K, PhantomData<&'a bool>)), Exclusive((K, PhantomData<&'a bool>)), + InclusiveRaw(Vec), + ExclusiveRaw(Vec), } impl<'a, K: PrimaryKey<'a>> Bound<'a, K> { @@ -67,8 +69,10 @@ impl<'a, K: PrimaryKey<'a>> Bound<'a, K> { pub fn to_raw_bound(&self) -> RawBound { match self { - Bound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_key()), Bound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_key()), + Bound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_key()), + Bound::ExclusiveRaw(raw_k) => RawBound::Exclusive(raw_k.clone()), + Bound::InclusiveRaw(raw_k) => RawBound::Inclusive(raw_k.clone()), } } } @@ -423,7 +427,7 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Inclusive(b"ra".to_vec())), + Some(Bound::inclusive(b"ra".to_vec())), None, Order::Ascending, ) @@ -433,7 +437,7 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Exclusive(b"ra".to_vec())), + Some(Bound::exclusive(b"ra".to_vec())), None, Order::Ascending, ) @@ -443,7 +447,7 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Exclusive(b"r".to_vec())), + Some(Bound::exclusive(b"r".to_vec())), None, Order::Ascending, ) @@ -455,7 +459,7 @@ mod test { .range_raw( &store, None, - Some(RawBound::Inclusive(b"ra".to_vec())), + Some(Bound::inclusive(b"ra".to_vec())), Order::Descending, ) .collect(); @@ -465,7 +469,7 @@ mod test { .range_raw( &store, None, - Some(RawBound::Exclusive(b"ra".to_vec())), + Some(Bound::exclusive(b"ra".to_vec())), Order::Descending, ) .collect(); @@ -475,7 +479,7 @@ mod test { .range_raw( &store, None, - Some(RawBound::Exclusive(b"rb".to_vec())), + Some(Bound::exclusive(b"rb".to_vec())), Order::Descending, ) .collect(); @@ -485,8 +489,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Inclusive(b"ra".to_vec())), - Some(RawBound::Exclusive(b"zi".to_vec())), + Some(Bound::inclusive(b"ra".to_vec())), + Some(Bound::exclusive(b"zi".to_vec())), Order::Ascending, ) .collect(); @@ -495,8 +499,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Inclusive(b"ra".to_vec())), - Some(RawBound::Exclusive(b"zi".to_vec())), + Some(Bound::inclusive(b"ra".to_vec())), + Some(Bound::exclusive(b"zi".to_vec())), Order::Descending, ) .collect(); @@ -505,8 +509,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Inclusive(b"ra".to_vec())), - Some(RawBound::Inclusive(b"zi".to_vec())), + Some(Bound::inclusive(b"ra".to_vec())), + Some(Bound::inclusive(b"zi".to_vec())), Order::Descending, ) .collect(); @@ -515,8 +519,8 @@ mod test { let res: StdResult> = prefix .range_raw( &store, - Some(RawBound::Exclusive(b"ra".to_vec())), - Some(RawBound::Exclusive(b"zi".to_vec())), + Some(Bound::exclusive(b"ra".to_vec())), + Some(Bound::exclusive(b"zi".to_vec())), Order::Ascending, ) .collect(); diff --git a/packages/storage-plus/src/snapshot/item.rs b/packages/storage-plus/src/snapshot/item.rs index 1fe58c332..51daaa6d2 100644 --- a/packages/storage-plus/src/snapshot/item.rs +++ b/packages/storage-plus/src/snapshot/item.rs @@ -132,6 +132,7 @@ where #[cfg(test)] mod tests { use super::*; + use crate::prefix::Bound; use cosmwasm_std::testing::MockStorage; type TestItem = SnapshotItem<'static, u64>; @@ -283,7 +284,6 @@ mod tests { #[test] #[cfg(feature = "iterator")] fn changelog_range_works() { - use crate::RawBound; use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -316,12 +316,7 @@ mod tests { // let's try to iterate over a changelog range let all: StdResult> = EVERY .changelog() - .range( - &store, - Some(RawBound::exclusive_int(3u64)), - None, - Order::Ascending, - ) + .range(&store, Some(Bound::exclusive(3u64)), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index db142e4a8..fd003faaf 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -514,12 +514,7 @@ mod tests { let all: StdResult> = EVERY .changelog() .prefix("A") - .range( - &store, - Some(RawBound::inclusive_int(3u64)), - None, - Order::Ascending, - ) + .range(&store, Some(Bound::inclusive(3u64)), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); @@ -542,12 +537,7 @@ mod tests { // let's try to iterate over a range let all: StdResult> = EVERY - .range( - &store, - Some(RawBound::Inclusive(b"C".to_vec())), - None, - Order::Ascending, - ) + .range(&store, Some(Bound::inclusive("C")), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -555,12 +545,7 @@ mod tests { // let's try to iterate over a more restrictive range let all: StdResult> = EVERY - .range( - &store, - Some(RawBound::Inclusive(b"D".to_vec())), - None, - Order::Ascending, - ) + .range(&store, Some(Bound::inclusive("D")), None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); From 1db0b8c50068084f2654d0c14bd4770722e8433f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 10:55:12 +0100 Subject: [PATCH 18/30] Publish Bound enum and Bounder trait --- packages/storage-plus/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 35200acff..d560020d9 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -28,11 +28,11 @@ pub use indexes::UniqueIndex; pub use indexes::{index_string, index_string_tuple, index_triple, index_tuple, Index}; pub use int_key::CwIntKey; pub use item::Item; -pub use keys::{Key, Prefixer, PrimaryKey}; +pub use keys::{Bounder, Key, Prefixer, PrimaryKey}; pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] -pub use prefix::{range_with_prefix, Prefix, PrefixBound, RawBound}; +pub use prefix::{range_with_prefix, Bound, Prefix, PrefixBound, RawBound}; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; From ef1d2cc7ed08be36a63ab80d4584e18c43365763 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 11:40:22 +0100 Subject: [PATCH 19/30] Migrate packages to Bound --- packages/utils/src/pagination.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/utils/src/pagination.rs b/packages/utils/src/pagination.rs index ba6e825a1..a88996acb 100644 --- a/packages/utils/src/pagination.rs +++ b/packages/utils/src/pagination.rs @@ -37,7 +37,7 @@ pub fn calc_range_start_string(start_after: Option) -> Option> { mod test { use super::*; use cosmwasm_std::{testing::mock_dependencies, Order}; - use cw_storage_plus::{RawBound, Map}; + use cw_storage_plus::{Bound, Map}; pub const HOLDERS: Map<&Addr, usize> = Map::new("some_data"); const LIMIT: usize = 30; @@ -64,7 +64,7 @@ mod test { Some(addr_from_i(j * LIMIT - 1)) }; - let start = calc_range_start(start_after).map(RawBound::exclusive); + let start = calc_range_start(start_after).map(Bound::ExclusiveRaw); let holders = HOLDERS .keys(&deps.storage, start, None, Order::Ascending) @@ -93,7 +93,7 @@ mod test { for j in 0..4 { let end_before = Some(addr_from_i(total_elements_count - j * LIMIT)); - let end = calc_range_end(end_before).map(RawBound::exclusive); + let end = calc_range_end(end_before).map(Bound::ExclusiveRaw); let holders = HOLDERS .keys(&deps.storage, None, end, Order::Descending) From 828dd1a8d8eea6ffc816b09d5d77e26dc00deba7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 14:24:53 +0100 Subject: [PATCH 20/30] Migrate contracts to type safe Bound --- contracts/cw1-subkeys/src/contract.rs | 6 +++--- contracts/cw1155-base/src/contract.rs | 8 ++++---- contracts/cw20-base/src/enumerable.rs | 6 +++--- contracts/cw3-fixed-multisig/src/contract.rs | 10 +++++----- contracts/cw3-flex-multisig/src/contract.rs | 8 ++++---- contracts/cw4-group/src/contract.rs | 4 ++-- contracts/cw4-stake/src/contract.rs | 4 ++-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index e6535ae2f..0b6fe1165 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -18,7 +18,7 @@ use cw1_whitelist::{ state::ADMIN_LIST, }; use cw2::{get_contract_version, set_contract_version}; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; use cw_utils::Expiration; use semver::Version; @@ -407,7 +407,7 @@ pub fn query_all_allowances( ) -> StdResult { let limit = calc_limit(limit); // we use raw addresses here.... - let start = start_after.map(RawBound::exclusive); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); let allowances = ALLOWANCES .range(deps.storage, start, None, Order::Ascending) @@ -437,7 +437,7 @@ pub fn query_all_permissions( limit: Option, ) -> StdResult { let limit = calc_limit(limit); - let start = start_after.map(RawBound::exclusive); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); let permissions = PERMISSIONS .range(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 4f254a144..8150809f1 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -3,7 +3,7 @@ use cosmwasm_std::{ to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, SubMsg, Uint128, }; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; use cw1155::{ ApproveAllEvent, ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, @@ -494,7 +494,7 @@ fn query_all_approvals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(|addr| RawBound::exclusive(addr.as_ref())); + let start = start_after.as_ref().map(Bound::exclusive); let operators = APPROVES .prefix(&owner) @@ -513,7 +513,7 @@ fn query_tokens( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive); + let start = start_after.as_ref().map(|s| Bound::exclusive(s.as_str())); let tokens = BALANCES .prefix(&owner) @@ -529,7 +529,7 @@ fn query_all_tokens( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive); + let start = start_after.as_ref().map(|s| Bound::exclusive(s.as_str())); let tokens = TOKENS .keys(deps.storage, start, None, Order::Ascending) .take(limit) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 2d165a1d5..aa5998d86 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -2,7 +2,7 @@ use cosmwasm_std::{Deps, Order, StdResult}; use cw20::{AllAccountsResponse, AllAllowancesResponse, AllowanceInfo}; use crate::state::{ALLOWANCES, BALANCES}; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; // settings for pagination const MAX_LIMIT: u32 = 30; @@ -16,7 +16,7 @@ pub fn query_all_allowances( ) -> StdResult { let owner_addr = deps.api.addr_validate(&owner)?; let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.as_bytes().into())); let allowances = ALLOWANCES .prefix(&owner_addr) @@ -39,7 +39,7 @@ pub fn query_all_accounts( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); let accounts = BALANCES .keys(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 284df3c93..5928bcf82 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -12,7 +12,7 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; use cw_utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; @@ -287,7 +287,7 @@ fn list_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive_int); + let start = start_after.map(Bound::exclusive); let proposals = PROPOSALS .range(deps.storage, start, None, Order::Ascending) .take(limit) @@ -304,7 +304,7 @@ fn reverse_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let end = start_before.map(RawBound::exclusive_int); + let end = start_before.map(Bound::exclusive); let props: StdResult> = PROPOSALS .range(deps.storage, None, end, Order::Descending) .take(limit) @@ -351,7 +351,7 @@ fn list_votes( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); let votes = BALLOTS .prefix(proposal_id) @@ -381,7 +381,7 @@ fn list_voters( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); let voters = VOTERS .range(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 50243ab59..6b31f1071 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -14,7 +14,7 @@ use cw3::{ }; use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; @@ -315,7 +315,7 @@ fn list_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(RawBound::exclusive_int); + let start = start_after.map(Bound::exclusive); let proposals = PROPOSALS .range(deps.storage, start, None, Order::Ascending) .take(limit) @@ -332,7 +332,7 @@ fn reverse_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let end = start_before.map(RawBound::exclusive_int); + let end = start_before.map(Bound::exclusive); let props: StdResult> = PROPOSALS .range(deps.storage, None, end, Order::Descending) .take(limit) @@ -380,7 +380,7 @@ fn list_votes( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let addr = maybe_addr(deps.api, start_after)?; - let start = addr.map(|addr| RawBound::exclusive(addr.as_ref())); + let start = addr.as_ref().map(Bound::exclusive); let votes = BALLOTS .prefix(proposal_id) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 9a7a86cde..913d427f6 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -9,7 +9,7 @@ use cw4::{ Member, MemberChangedHookMsg, MemberDiff, MemberListResponse, MemberResponse, TotalWeightResponse, }; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; use cw_utils::maybe_addr; use crate::error::ContractError; @@ -190,7 +190,7 @@ fn list_members( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let addr = maybe_addr(deps.api, start_after)?; - let start = addr.map(|addr| RawBound::exclusive(addr.to_string())); + let start = addr.as_ref().map(Bound::exclusive); let members = MEMBERS .range(deps.storage, start, None, Order::Ascending) diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 28b91ef1a..6b51897b5 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -11,7 +11,7 @@ use cw4::{ Member, MemberChangedHookMsg, MemberDiff, MemberListResponse, MemberResponse, TotalWeightResponse, }; -use cw_storage_plus::RawBound; +use cw_storage_plus::Bound; use cw_utils::{maybe_addr, NativeBalance}; use crate::error::ContractError; @@ -339,7 +339,7 @@ fn list_members( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let addr = maybe_addr(deps.api, start_after)?; - let start = addr.map(|addr| RawBound::exclusive(addr.as_ref())); + let start = addr.as_ref().map(Bound::exclusive); let members = MEMBERS .range(deps.storage, start, None, Order::Ascending) From 849c55be92c36bd3cb58b7cd8bedb0cd1492fb6c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 14:53:25 +0100 Subject: [PATCH 21/30] Implement Bounder for IntKeyOld --- packages/storage-plus/src/keys_old.rs | 16 +++++++++++++++- packages/storage-plus/src/map.rs | 8 +++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/keys_old.rs b/packages/storage-plus/src/keys_old.rs index d864153e2..8a25617fe 100644 --- a/packages/storage-plus/src/keys_old.rs +++ b/packages/storage-plus/src/keys_old.rs @@ -1,6 +1,6 @@ use crate::de::KeyDeserialize; use crate::keys::Key; -use crate::{Endian, Prefixer, PrimaryKey}; +use crate::{Bound, Bounder, Endian, Prefixer, PrimaryKey}; use std::marker::PhantomData; #[derive(Clone, Debug, PartialEq, Eq)] @@ -61,6 +61,20 @@ impl<'a, T: Endian> Prefixer<'a> for IntKeyOld { } } +// this auto-implements Bounder for all the IntKey types +impl<'a, T: Endian> Bounder<'a> for IntKeyOld +where + IntKeyOld: KeyDeserialize, +{ + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 6ebe57da7..029a5c279 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -263,7 +263,7 @@ mod test { use cosmwasm_std::{Order, StdResult}; use crate::int_key::CwIntKey; - // use crate::keys_old::IntKeyOld; + use crate::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { @@ -274,8 +274,8 @@ mod test { const PEOPLE: Map<&[u8], Data> = Map::new("people"); #[cfg(feature = "iterator")] const PEOPLE_ID: Map = Map::new("people_id"); - // #[cfg(feature = "iterator")] - // const SIGNED_ID_OLD: Map, Data> = Map::new("signed_id"); + #[cfg(feature = "iterator")] + const SIGNED_ID_OLD: Map, Data> = Map::new("signed_id"); #[cfg(feature = "iterator")] const SIGNED_ID: Map = Map::new("signed_id"); @@ -803,7 +803,6 @@ mod test { assert_eq!(all, vec![(50, data3)]); } - /* #[test] #[cfg(feature = "iterator")] fn range_signed_integer_key_migration() { @@ -873,7 +872,6 @@ mod test { // confirm new order is right assert_eq!(new, vec![(-1234, data), (-56, data2), (50, data3)]); } - */ #[test] #[cfg(feature = "iterator")] From 393abb95b8c922e165e2bf5cf5f5f021fe5ddba9 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 14:58:35 +0100 Subject: [PATCH 22/30] Remove obsolete RawBound helpers --- packages/storage-plus/src/prefix.rs | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 01edfbb34..3dcc42ab9 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -8,10 +8,9 @@ use std::ops::Deref; use crate::de::KeyDeserialize; use crate::helpers::{namespaces_with_key, nested_namespaces_with_key}; -use crate::int_key::CwIntKey; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; use crate::keys::Key; -use crate::{Endian, Prefixer, PrimaryKey}; +use crate::{Prefixer, PrimaryKey}; /// `RawBound` is used to define the two ends of a range, more explicit than `Option`. /// `None` means that we don't limit that side of the range at all. @@ -24,28 +23,6 @@ pub enum RawBound { Exclusive(Vec), } -impl RawBound { - /// Turns optional binary, like Option into an inclusive bound - pub fn inclusive>>(limit: T) -> Self { - RawBound::Inclusive(limit.into()) - } - - /// Turns optional binary, like Option into an exclusive bound - pub fn exclusive>>(limit: T) -> Self { - RawBound::Exclusive(limit.into()) - } - - /// Turns an int, like Option into an inclusive bound - pub fn inclusive_int(limit: T) -> Self { - RawBound::Inclusive(limit.to_cw_bytes().into()) - } - - /// Turns an int, like Option into an exclusive bound - pub fn exclusive_int(limit: T) -> Self { - RawBound::Exclusive(limit.to_cw_bytes().into()) - } -} - /// `Bound` is used to define the two ends of a range. /// `None` means that we don't limit that side of the range at all. /// `Inclusive` means we use the given value as a limit and *include* anything at that exact key. From 4e3ba553186ba0ce2c7b5f3f4ec9e358ef76b8e6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 20:40:52 +0100 Subject: [PATCH 23/30] Fix MultiIndex bound type Use tuple of IK and PK for multi index bound type --- packages/storage-plus/src/indexed_map.rs | 35 +++++++++++----------- packages/storage-plus/src/indexes/multi.rs | 23 +++++++------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 67ab57652..c41dc5872 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -449,19 +449,26 @@ mod test { .count(); assert_eq!(0, count); - // index_key() over MultiIndex works (empty pk) - // In a MultiIndex, an index key is composed by the index and the primary key. + // In a MultiIndex, the index key is composed by the index and the primary key. // Primary key may be empty (so that to iterate over all elements that match just the index) + let key = ("Maria".to_string(), "".to_string()); + // Iterate using an inclusive bound over the key + let count = map + .idx + .name + .range_raw(&store, Some(Bound::inclusive(key)), None, Order::Ascending) + .count(); + // gets from the first "Maria" until the end + assert_eq!(4, count); + + // This is equivalent to using prefix_range let key = "Maria".to_string(); - // Use the index_key() helper to build the (raw) index key with an empty pk - let key = map.idx.name.index_key(key); - // Iterate using a bound over the raw key let count = map .idx .name - .range_raw( + .prefix_range_raw( &store, - Some(Bound::InclusiveRaw(key)), + Some(PrefixBound::inclusive(key)), None, Order::Ascending, ) @@ -469,29 +476,21 @@ mod test { // gets from the first "Maria" until the end assert_eq!(4, count); - // index_key() over MultiIndex works (non-empty pk) // Build key including a non-empty pk let key = ("Maria".to_string(), "1".to_string()); - // Use the joined_key() helper to build the (raw) index key - let key = key.joined_key(); - // Iterate using a (exclusive) bound over the raw key. + // Iterate using a (exclusive) bound over the key. // (Useful for pagination / continuation contexts). let count = map .idx .name - .range_raw( - &store, - Some(Bound::ExclusiveRaw(key)), - None, - Order::Ascending, - ) + .range_raw(&store, Some(Bound::exclusive(key)), None, Order::Ascending) .count(); // gets from the 2nd "Maria" until the end assert_eq!(3, count); // index_key() over UniqueIndex works. let age_key = 23u32; - // Iterate using a (inclusive) bound over the raw key. + // Iterate using a (inclusive) bound over the key. let count = map .idx .age diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 3ea4c6bbb..e61d2f061 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -143,7 +143,7 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + Prefixer<'a>, { - fn no_prefix_raw(&self) -> Prefix, T, IK> { + fn no_prefix_raw(&self) -> Prefix, T, (IK, PK)> { Prefix::with_deserialization_functions( self.idx_namespace, &[], @@ -191,15 +191,16 @@ where impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> where T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a> + Prefixer<'a>, + IK: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, + PK: PrimaryKey<'a> + KeyDeserialize, { // I would prefer not to copy code from Prefix, but no other way // with lifetimes (create Prefix inside function and return ref = no no) pub fn range_raw<'c>( &'c self, store: &'c dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: Order, ) -> Box>> + 'c> where @@ -211,8 +212,8 @@ where pub fn keys_raw<'c>( &'c self, store: &'c dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: Order, ) -> Box> + 'c> { self.no_prefix_raw().keys_raw(store, min, max, order) @@ -304,8 +305,8 @@ where pub fn range<'c>( &self, store: &'c dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -318,8 +319,8 @@ where pub fn keys<'c>( &self, store: &'c dyn Storage, - min: Option>, - max: Option>, + min: Option>, + max: Option>, order: cosmwasm_std::Order, ) -> Box> + 'c> where @@ -329,7 +330,7 @@ where self.no_prefix().keys(store, min, max, order) } - fn no_prefix(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &[], From 321cc9c152b476b9f0a3b4cf226af257aa229aba Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 20:52:51 +0100 Subject: [PATCH 24/30] Improve indexed map multi index tests --- packages/storage-plus/src/indexed_map.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index c41dc5872..b6098e49c 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -453,17 +453,18 @@ mod test { // Primary key may be empty (so that to iterate over all elements that match just the index) let key = ("Maria".to_string(), "".to_string()); // Iterate using an inclusive bound over the key - let count = map + let marias = map .idx .name .range_raw(&store, Some(Bound::inclusive(key)), None, Order::Ascending) - .count(); + .collect::>>() + .unwrap(); // gets from the first "Maria" until the end - assert_eq!(4, count); + assert_eq!(4, marias.len()); // This is equivalent to using prefix_range let key = "Maria".to_string(); - let count = map + let marias2 = map .idx .name .prefix_range_raw( @@ -472,9 +473,10 @@ mod test { None, Order::Ascending, ) - .count(); - // gets from the first "Maria" until the end - assert_eq!(4, count); + .collect::>>() + .unwrap(); + assert_eq!(4, marias2.len()); + assert_eq!(marias, marias2); // Build key including a non-empty pk let key = ("Maria".to_string(), "1".to_string()); From 6bb789662e2dacce793750ece220c88e476133f0 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 9 Jan 2022 18:14:23 +0100 Subject: [PATCH 25/30] Refactor bounds into own module --- packages/storage-plus/src/bound.rs | 184 ++++++++++++++++++ packages/storage-plus/src/indexed_map.rs | 5 +- packages/storage-plus/src/indexed_snapshot.rs | 5 +- packages/storage-plus/src/indexes/multi.rs | 5 +- packages/storage-plus/src/indexes/unique.rs | 5 +- packages/storage-plus/src/keys.rs | 113 ----------- packages/storage-plus/src/keys_old.rs | 5 +- packages/storage-plus/src/lib.rs | 7 +- packages/storage-plus/src/map.rs | 8 +- packages/storage-plus/src/prefix.rs | 68 +------ packages/storage-plus/src/snapshot/item.rs | 2 +- packages/storage-plus/src/snapshot/map.rs | 5 +- packages/storage-plus/src/snapshot/mod.rs | 2 +- 13 files changed, 217 insertions(+), 197 deletions(-) create mode 100644 packages/storage-plus/src/bound.rs diff --git a/packages/storage-plus/src/bound.rs b/packages/storage-plus/src/bound.rs new file mode 100644 index 000000000..597b569b9 --- /dev/null +++ b/packages/storage-plus/src/bound.rs @@ -0,0 +1,184 @@ +#![cfg(feature = "iterator")] + +use cosmwasm_std::Addr; +use std::marker::PhantomData; + +use crate::de::KeyDeserialize; +use crate::{Prefixer, PrimaryKey}; + +/// `RawBound` is used to define the two ends of a range, more explicit than `Option`. +/// `None` means that we don't limit that side of the range at all. +/// `Inclusive` means we use the given bytes as a limit and *include* anything at that exact key. +/// `Exclusive` means we use the given bytes as a limit and *exclude* anything at that exact key. +/// See `Bound` for a type safe way to build these bounds. +#[derive(Clone, Debug)] +pub enum RawBound { + Inclusive(Vec), + Exclusive(Vec), +} + +/// `Bound` is used to define the two ends of a range. +/// `None` means that we don't limit that side of the range at all. +/// `Inclusive` means we use the given value as a limit and *include* anything at that exact key. +/// `Exclusive` means we use the given value as a limit and *exclude* anything at that exact key. +#[derive(Clone, Debug)] +pub enum Bound<'a, K: PrimaryKey<'a>> { + Inclusive((K, PhantomData<&'a bool>)), + Exclusive((K, PhantomData<&'a bool>)), + InclusiveRaw(Vec), + ExclusiveRaw(Vec), +} + +impl<'a, K: PrimaryKey<'a>> Bound<'a, K> { + pub fn inclusive>(k: T) -> Self { + Self::Inclusive((k.into(), PhantomData)) + } + + pub fn exclusive>(k: T) -> Self { + Self::Exclusive((k.into(), PhantomData)) + } + + pub fn to_raw_bound(&self) -> RawBound { + match self { + Bound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_key()), + Bound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_key()), + Bound::ExclusiveRaw(raw_k) => RawBound::Exclusive(raw_k.clone()), + Bound::InclusiveRaw(raw_k) => RawBound::Inclusive(raw_k.clone()), + } + } +} + +#[derive(Clone, Debug)] +pub enum PrefixBound<'a, K: Prefixer<'a>> { + Inclusive((K, PhantomData<&'a bool>)), + Exclusive((K, PhantomData<&'a bool>)), +} + +impl<'a, K: Prefixer<'a>> PrefixBound<'a, K> { + pub fn inclusive>(k: T) -> Self { + Self::Inclusive((k.into(), PhantomData)) + } + + pub fn exclusive>(k: T) -> Self { + Self::Exclusive((k.into(), PhantomData)) + } + + pub fn to_raw_bound(&self) -> RawBound { + match self { + PrefixBound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_prefix()), + PrefixBound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_prefix()), + } + } +} + +pub trait Bounder<'a>: PrimaryKey<'a> + Sized { + fn inclusive_bound(self) -> Option>; + fn exclusive_bound(self) -> Option>; +} + +impl<'a> Bounder<'a> for () { + fn inclusive_bound(self) -> Option> { + None + } + fn exclusive_bound(self) -> Option> { + None + } +} + +impl<'a> Bounder<'a> for &'a [u8] { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl< + 'a, + T: PrimaryKey<'a> + KeyDeserialize + Prefixer<'a> + Clone, + U: PrimaryKey<'a> + KeyDeserialize + Clone, + > Bounder<'a> for (T, U) +{ + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl< + 'a, + T: PrimaryKey<'a> + Prefixer<'a> + Clone, + U: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize + Clone, + V: PrimaryKey<'a> + KeyDeserialize + Clone, + > Bounder<'a> for (T, U, V) +{ + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl<'a> Bounder<'a> for &'a str { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl<'a> Bounder<'a> for String { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl<'a> Bounder<'a> for Vec { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl<'a> Bounder<'a> for &'a Addr { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +impl<'a> Bounder<'a> for Addr { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +macro_rules! integer_bound { + (for $($t:ty),+) => { + $(impl<'a> Bounder<'a> for $t { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } + })* + } +} + +integer_bound!(for i8, u8, i16, u16, i32, u32, i64, u64); diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index b6098e49c..4033f2606 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -1,6 +1,7 @@ // this module requires iterator to be useful at all #![cfg(feature = "iterator")] +use crate::PrefixBound; use cosmwasm_std::{StdError, StdResult, Storage}; use serde::de::DeserializeOwned; use serde::Serialize; @@ -10,8 +11,8 @@ use crate::indexes::Index; use crate::iter_helpers::{deserialize_kv, deserialize_v}; use crate::keys::{Prefixer, PrimaryKey}; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; -use crate::Path; +use crate::prefix::{namespaced_prefix_range, Prefix}; +use crate::{Bound, Path}; pub trait IndexList { fn get_indexes(&'_ self) -> Box> + '_>; diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index f15297506..60029b1b0 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -8,9 +8,10 @@ use serde::Serialize; use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::keys::{Prefixer, PrimaryKey}; -use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Prefix}; use crate::snapshot::{ChangeSet, SnapshotMap}; -use crate::{IndexList, Map, Path, Strategy}; +use crate::PrefixBound; +use crate::{Bound, IndexList, Map, Path, Strategy}; /// `IndexedSnapshotMap` works like a `SnapshotMap` but has a secondary index pub struct IndexedSnapshotMap<'a, K, T, I> { diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index e61d2f061..89209718a 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -6,12 +6,13 @@ use serde::Serialize; use cosmwasm_std::{from_slice, Order, Record, StdError, StdResult, Storage}; +use crate::bound::PrefixBound; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::iter_helpers::deserialize_kv; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, Bound, PrefixBound}; -use crate::{Index, Prefix, Prefixer, PrimaryKey}; +use crate::prefix::namespaced_prefix_range; +use crate::{Bound, Index, Prefix, Prefixer, PrimaryKey}; use std::marker::PhantomData; /// MultiIndex stores (namespace, index_name, idx_value, pk) -> b"pk_len". diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 9200ce552..3143e5cff 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -8,11 +8,12 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{from_slice, Binary, Order, Record, StdError, StdResult, Storage}; +use crate::bound::PrefixBound; use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::map::Map; -use crate::prefix::{namespaced_prefix_range, Bound, PrefixBound}; -use crate::{Index, Prefix, Prefixer, PrimaryKey}; +use crate::prefix::namespaced_prefix_range; +use crate::{Bound, Index, Prefix, Prefixer, PrimaryKey}; /// UniqueRef stores Binary(Vec[u8]) representation of private key and index value #[derive(Deserialize, Serialize)] diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index b0285194a..e4240abb1 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -3,7 +3,6 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::int_key::CwIntKey; -use crate::prefix::Bound; #[derive(Debug)] pub enum Key<'a> { @@ -301,118 +300,6 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); -pub trait Bounder<'a>: PrimaryKey<'a> + Sized { - fn inclusive_bound(self) -> Option>; - fn exclusive_bound(self) -> Option>; -} - -impl<'a> Bounder<'a> for () { - fn inclusive_bound(self) -> Option> { - None - } - fn exclusive_bound(self) -> Option> { - None - } -} - -impl<'a> Bounder<'a> for &'a [u8] { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl< - 'a, - T: PrimaryKey<'a> + KeyDeserialize + Prefixer<'a> + Clone, - U: PrimaryKey<'a> + KeyDeserialize + Clone, - > Bounder<'a> for (T, U) -{ - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl< - 'a, - T: PrimaryKey<'a> + Prefixer<'a> + Clone, - U: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize + Clone, - V: PrimaryKey<'a> + KeyDeserialize + Clone, - > Bounder<'a> for (T, U, V) -{ - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl<'a> Bounder<'a> for &'a str { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl<'a> Bounder<'a> for String { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl<'a> Bounder<'a> for Vec { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl<'a> Bounder<'a> for &'a Addr { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -impl<'a> Bounder<'a> for Addr { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - -macro_rules! integer_bound { - (for $($t:ty),+) => { - $(impl<'a> Bounder<'a> for $t { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } - })* - } -} - -integer_bound!(for i8, u8, i16, u16, i32, u32, i64, u64); - #[cfg(test)] mod test { use super::*; diff --git a/packages/storage-plus/src/keys_old.rs b/packages/storage-plus/src/keys_old.rs index 8a25617fe..97752ae03 100644 --- a/packages/storage-plus/src/keys_old.rs +++ b/packages/storage-plus/src/keys_old.rs @@ -1,6 +1,8 @@ use crate::de::KeyDeserialize; use crate::keys::Key; -use crate::{Bound, Bounder, Endian, Prefixer, PrimaryKey}; +#[cfg(feature = "iterator")] +use crate::{Bound, Bounder}; +use crate::{Endian, Prefixer, PrimaryKey}; use std::marker::PhantomData; #[derive(Clone, Debug, PartialEq, Eq)] @@ -62,6 +64,7 @@ impl<'a, T: Endian> Prefixer<'a> for IntKeyOld { } // this auto-implements Bounder for all the IntKey types +#[cfg(feature = "iterator")] impl<'a, T: Endian> Bounder<'a> for IntKeyOld where IntKeyOld: KeyDeserialize, diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index d560020d9..0d6e464c9 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -1,3 +1,4 @@ +mod bound; mod de; mod de_old; mod endian; @@ -15,6 +16,8 @@ mod path; mod prefix; mod snapshot; +#[cfg(feature = "iterator")] +pub use bound::{Bound, Bounder, PrefixBound, RawBound}; pub use endian::Endian; #[cfg(feature = "iterator")] pub use indexed_map::{IndexList, IndexedMap}; @@ -28,11 +31,11 @@ pub use indexes::UniqueIndex; pub use indexes::{index_string, index_string_tuple, index_triple, index_tuple, Index}; pub use int_key::CwIntKey; pub use item::Item; -pub use keys::{Bounder, Key, Prefixer, PrimaryKey}; +pub use keys::{Key, Prefixer, PrimaryKey}; pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] -pub use prefix::{range_with_prefix, Bound, Prefix, PrefixBound, RawBound}; +pub use prefix::{range_with_prefix, Prefix}; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 029a5c279..2d00cc4de 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -2,6 +2,8 @@ use serde::de::DeserializeOwned; use serde::Serialize; use std::marker::PhantomData; +#[cfg(feature = "iterator")] +use crate::bound::{Bound, Bounder, PrefixBound}; #[cfg(feature = "iterator")] use crate::de::KeyDeserialize; use crate::helpers::query_raw; @@ -9,11 +11,10 @@ use crate::helpers::query_raw; use crate::iter_helpers::{deserialize_kv, deserialize_v}; #[cfg(feature = "iterator")] use crate::keys::Prefixer; -use crate::keys::{Bounder, Key, PrimaryKey}; +use crate::keys::{Key, PrimaryKey}; use crate::path::Path; -use crate::prefix::Bound; #[cfg(feature = "iterator")] -use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Prefix}; use cosmwasm_std::{from_slice, Addr, QuerierWrapper, StdError, StdResult, Storage}; #[derive(Debug, Clone)] @@ -263,6 +264,7 @@ mod test { use cosmwasm_std::{Order, StdResult}; use crate::int_key::CwIntKey; + #[cfg(feature = "iterator")] use crate::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 3dcc42ab9..2ee04233a 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -6,76 +6,12 @@ use std::marker::PhantomData; use cosmwasm_std::{Order, Record, StdResult, Storage}; use std::ops::Deref; +use crate::bound::{PrefixBound, RawBound}; use crate::de::KeyDeserialize; use crate::helpers::{namespaces_with_key, nested_namespaces_with_key}; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; use crate::keys::Key; -use crate::{Prefixer, PrimaryKey}; - -/// `RawBound` is used to define the two ends of a range, more explicit than `Option`. -/// `None` means that we don't limit that side of the range at all. -/// `Inclusive` means we use the given bytes as a limit and *include* anything at that exact key. -/// `Exclusive` means we use the given bytes as a limit and *exclude* anything at that exact key. -/// See `Bound` for a type safe way to build these bounds. -#[derive(Clone, Debug)] -pub enum RawBound { - Inclusive(Vec), - Exclusive(Vec), -} - -/// `Bound` is used to define the two ends of a range. -/// `None` means that we don't limit that side of the range at all. -/// `Inclusive` means we use the given value as a limit and *include* anything at that exact key. -/// `Exclusive` means we use the given value as a limit and *exclude* anything at that exact key. -#[derive(Clone, Debug)] -pub enum Bound<'a, K: PrimaryKey<'a>> { - Inclusive((K, PhantomData<&'a bool>)), - Exclusive((K, PhantomData<&'a bool>)), - InclusiveRaw(Vec), - ExclusiveRaw(Vec), -} - -impl<'a, K: PrimaryKey<'a>> Bound<'a, K> { - pub fn inclusive>(k: T) -> Self { - Self::Inclusive((k.into(), PhantomData)) - } - - pub fn exclusive>(k: T) -> Self { - Self::Exclusive((k.into(), PhantomData)) - } - - pub fn to_raw_bound(&self) -> RawBound { - match self { - Bound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_key()), - Bound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_key()), - Bound::ExclusiveRaw(raw_k) => RawBound::Exclusive(raw_k.clone()), - Bound::InclusiveRaw(raw_k) => RawBound::Inclusive(raw_k.clone()), - } - } -} - -#[derive(Clone, Debug)] -pub enum PrefixBound<'a, K: Prefixer<'a>> { - Inclusive((K, PhantomData<&'a bool>)), - Exclusive((K, PhantomData<&'a bool>)), -} - -impl<'a, K: Prefixer<'a>> PrefixBound<'a, K> { - pub fn inclusive>(k: T) -> Self { - Self::Inclusive((k.into(), PhantomData)) - } - - pub fn exclusive>(k: T) -> Self { - Self::Exclusive((k.into(), PhantomData)) - } - - pub fn to_raw_bound(&self) -> RawBound { - match self { - PrefixBound::Exclusive((k, _)) => RawBound::Exclusive(k.joined_prefix()), - PrefixBound::Inclusive((k, _)) => RawBound::Inclusive(k.joined_prefix()), - } - } -} +use crate::{Bound, Prefixer, PrimaryKey}; type DeserializeVFn = fn(&dyn Storage, &[u8], Record) -> StdResult>; diff --git a/packages/storage-plus/src/snapshot/item.rs b/packages/storage-plus/src/snapshot/item.rs index 51daaa6d2..633f073ff 100644 --- a/packages/storage-plus/src/snapshot/item.rs +++ b/packages/storage-plus/src/snapshot/item.rs @@ -132,7 +132,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::prefix::Bound; + use crate::bound::Bound; use cosmwasm_std::testing::MockStorage; type TestItem = SnapshotItem<'static, u64>; diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index fd003faaf..3d7e6b0e4 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -3,14 +3,15 @@ use serde::Serialize; use cosmwasm_std::{StdError, StdResult, Storage}; +use crate::bound::PrefixBound; use crate::de::KeyDeserialize; use crate::iter_helpers::deserialize_kv; use crate::keys::PrimaryKey; use crate::map::Map; use crate::path::Path; -use crate::prefix::{namespaced_prefix_range, Bound, Prefix, PrefixBound}; +use crate::prefix::{namespaced_prefix_range, Prefix}; use crate::snapshot::{ChangeSet, Snapshot}; -use crate::{Prefixer, Strategy}; +use crate::{Bound, Prefixer, Strategy}; /// Map that maintains a snapshots of one or more checkpoints. /// We can query historical data as well as current state. diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index bf2436c9e..d992743b9 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -5,8 +5,8 @@ mod map; pub use item::SnapshotItem; pub use map::SnapshotMap; +use crate::bound::Bound; use crate::de::KeyDeserialize; -use crate::prefix::Bound; use crate::{Map, Prefixer, PrimaryKey}; use cosmwasm_std::{Order, StdError, StdResult, Storage}; use serde::de::DeserializeOwned; From 96b937b600e41c2b6f9d47f44c4cd1127e0cb794 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 27 Jan 2022 22:05:27 +0100 Subject: [PATCH 26/30] Migrate cw20-ics20 to type safe Bound --- contracts/cw20-ics20/src/contract.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 8c705bd1f..82133c6a7 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -17,7 +17,7 @@ use crate::msg::{ ListAllowedResponse, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, TransferMsg, }; use crate::state::{AllowInfo, Config, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; -use cw_utils::{nonpayable, one_coin}; +use cw_utils::{maybe_addr, nonpayable, one_coin}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw20-ics20"; @@ -284,10 +284,8 @@ fn list_allowed( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = match start_after { - Some(x) => Some(Bound::exclusive(deps.api.addr_validate(&x)?.into_string())), - None => None, - }; + let addr = maybe_addr(deps.api, start_after)?; + let start = addr.as_ref().map(Bound::exclusive); let allow = ALLOW_LIST .range(deps.storage, start, None, Order::Ascending) From 1d9379a996a0a90192bd1346cf635f7e58a87eff Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 28 Jan 2022 15:12:10 +0100 Subject: [PATCH 27/30] Remove redundant test --- packages/storage-plus/src/map.rs | 60 -------------------------------- 1 file changed, 60 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 2d00cc4de..0bb6cd092 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -477,66 +477,6 @@ mod test { fn range_simple_string_key() { let mut store = MockStorage::new(); - // save and load on two keys - let data = Data { - name: "John".to_string(), - age: 32, - }; - PEOPLE.save(&mut store, b"john", &data).unwrap(); - - let data2 = Data { - name: "Jim".to_string(), - age: 44, - }; - PEOPLE.save(&mut store, b"jim", &data2).unwrap(); - - // let's try to iterate! - let all: StdResult> = PEOPLE.range(&store, None, None, Order::Ascending).collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![ - (b"jim".to_vec(), data2.clone()), - (b"john".to_vec(), data.clone()) - ] - ); - - // let's try to iterate over a range - let all: StdResult> = PEOPLE - .range( - &store, - Some(Bound::inclusive(b"j" as &[u8])), - None, - Order::Ascending, - ) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![(b"jim".to_vec(), data2), (b"john".to_vec(), data.clone())] - ); - - // let's try to iterate over a more restrictive range - let all: StdResult> = PEOPLE - .range( - &store, - Some(Bound::inclusive(b"jo" as &[u8])), - None, - Order::Ascending, - ) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![(b"john".to_vec(), data)]); - } - - #[test] - #[cfg(feature = "iterator")] - fn range2_simple_string_key() { - let mut store = MockStorage::new(); - // save and load on three keys let data = Data { name: "John".to_string(), From e0e60df3c8703c2490b9c5ac1e63b9475674ae98 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 28 Jan 2022 15:16:25 +0100 Subject: [PATCH 28/30] Rename tests for clarity --- packages/storage-plus/src/map.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 0bb6cd092..962e94297 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -581,9 +581,10 @@ mod test { assert_eq!(1, all.len()); assert_eq!(all, vec![(1234, data)]); } + #[test] #[cfg(feature = "iterator")] - fn range2_simple_integer_key() { + fn range_simple_integer_key_with_bounder_trait() { let mut store = MockStorage::new(); // save and load on two keys @@ -689,7 +690,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range2_simple_signed_integer_key() { + fn range_simple_signed_integer_key_with_bounder_trait() { let mut store = MockStorage::new(); // save and load on three keys From a3ea930b8a14a08db7c745ef63ad4211367931a5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 28 Jan 2022 15:22:35 +0100 Subject: [PATCH 29/30] Remove redundant / repeated test cases --- packages/storage-plus/src/map.rs | 109 ------------------------------- 1 file changed, 109 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 962e94297..0b50944ab 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -902,50 +902,6 @@ mod test { all, vec![(b"spender".to_vec(), 1000), (b"spender2".to_vec(), 3000),] ); - } - - #[test] - #[cfg(feature = "iterator")] - fn range2_composite_key() { - let mut store = MockStorage::new(); - - // save and load on three keys, one under different owner - ALLOWANCE - .save(&mut store, (b"owner", b"spender"), &1000) - .unwrap(); - ALLOWANCE - .save(&mut store, (b"owner", b"spender2"), &3000) - .unwrap(); - ALLOWANCE - .save(&mut store, (b"owner2", b"spender"), &5000) - .unwrap(); - - // let's try to iterate! - let all: StdResult> = ALLOWANCE - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(3, all.len()); - assert_eq!( - all, - vec![ - ((b"owner".to_vec(), b"spender".to_vec()), 1000), - ((b"owner".to_vec(), b"spender2".to_vec()), 3000), - ((b"owner2".to_vec(), b"spender".to_vec()), 5000) - ] - ); - - // let's try to iterate over a prefix - let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![(b"spender".to_vec(), 1000), (b"spender2".to_vec(), 3000),] - ); // let's try to iterate over a prefixed restricted inclusive range let all: StdResult> = ALLOWANCE @@ -1112,71 +1068,6 @@ mod test { ("recipient2".to_string(), 3000), ] ); - } - - #[test] - #[cfg(feature = "iterator")] - fn range2_triple_key() { - let mut store = MockStorage::new(); - - // save and load on three keys, one under different owner - TRIPLE - .save(&mut store, (b"owner", 9u8, "recipient"), &1000) - .unwrap(); - TRIPLE - .save(&mut store, (b"owner", 9u8, "recipient2"), &3000) - .unwrap(); - TRIPLE - .save(&mut store, (b"owner", 10u8, "recipient3"), &3000) - .unwrap(); - TRIPLE - .save(&mut store, (b"owner2", 9u8, "recipient"), &5000) - .unwrap(); - - // let's try to iterate! - let all: StdResult> = TRIPLE.range(&store, None, None, Order::Ascending).collect(); - let all = all.unwrap(); - assert_eq!(4, all.len()); - assert_eq!( - all, - vec![ - ((b"owner".to_vec(), 9, "recipient".to_string()), 1000), - ((b"owner".to_vec(), 9, "recipient2".to_string()), 3000), - ((b"owner".to_vec(), 10, "recipient3".to_string()), 3000), - ((b"owner2".to_vec(), 9, "recipient".to_string()), 5000) - ] - ); - - // let's iterate over a sub_prefix - let all: StdResult> = TRIPLE - .sub_prefix(b"owner") - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(3, all.len()); - assert_eq!( - all, - vec![ - ((9, "recipient".to_string()), 1000), - ((9, "recipient2".to_string()), 3000), - ((10, "recipient3".to_string()), 3000), - ] - ); - - // let's iterate over a prefix - let all: StdResult> = TRIPLE - .prefix((b"owner", 9)) - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![ - ("recipient".to_string(), 1000), - ("recipient2".to_string(), 3000), - ] - ); // let's try to iterate over a prefixed restricted inclusive range let all: StdResult> = TRIPLE From 2f8b9f97aaf460ceb901e0dc6f3fe14387504c5f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 28 Jan 2022 15:38:23 +0100 Subject: [PATCH 30/30] Update rust version in CI to current stable (1.58.1) Required for `edition2021` feature --- .circleci/config.yml | 140 +++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c991d2dd6..b10f55721 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,7 +52,7 @@ workflows: jobs: contract_cw1_subkeys: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw1-subkeys steps: - checkout: @@ -62,7 +62,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-subkeys-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-subkeys-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -75,11 +75,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-subkeys-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-subkeys-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw1-whitelist steps: - checkout: @@ -89,7 +89,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-whitelist-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -102,11 +102,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-whitelist-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist_ng: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw1-whitelist-ng steps: - checkout: @@ -116,7 +116,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-whitelist-ng-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-ng-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -129,11 +129,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-whitelist-ng-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-ng-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw3_fixed_multisig: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw3-fixed-multisig steps: - checkout: @@ -143,7 +143,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-fixed-multisig-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-fixed-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -156,11 +156,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-fixed-multisig-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-fixed-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw3_flex_multisig: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw3-flex-multisig steps: - checkout: @@ -170,7 +170,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-flex-multisig-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-flex-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -183,11 +183,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-flex-multisig-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-flex-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw4_group: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw4-group steps: - checkout: @@ -197,7 +197,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-group-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-group-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -210,11 +210,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-group-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-group-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw4_stake: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw4-stake steps: - checkout: @@ -224,7 +224,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-stake-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-stake-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -237,11 +237,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-stake-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-stake-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw20_base: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw20-base steps: - checkout: @@ -251,7 +251,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-base-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -264,11 +264,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-base-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw20_ics20: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw20-ics20 steps: - checkout: @@ -278,7 +278,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-ics20-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-ics20-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -291,11 +291,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-ics20-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-ics20-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} contract_cw1155_base: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/contracts/cw1155-base steps: - checkout: @@ -305,7 +305,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1155-base-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1155-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -318,11 +318,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1155-base-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1155-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_controllers: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/controllers steps: - checkout: @@ -332,7 +332,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-controllers:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-controllers:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -343,11 +343,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-controllers:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-controllers:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_utils: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/utils steps: - checkout: @@ -357,7 +357,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-utils:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-utils:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -368,11 +368,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-utils:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-utils:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_cw1: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/cw1 steps: - checkout: @@ -382,7 +382,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -396,11 +396,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_cw2: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/cw2 steps: - checkout: @@ -410,7 +410,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw2:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw2:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -422,11 +422,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw2:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw2:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_cw3: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/cw3 steps: - checkout: @@ -436,7 +436,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw3:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw3:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -450,11 +450,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw3:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw3:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_cw4: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/cw4 steps: - checkout: @@ -464,7 +464,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw4:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw4:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -478,11 +478,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw4:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw4:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_cw20: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/cw20 steps: - checkout: @@ -492,7 +492,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw20:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw20:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -506,11 +506,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw20:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw20:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_cw1155: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/cw1155 steps: - checkout: @@ -520,7 +520,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1155:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1155:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -534,11 +534,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1155:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1155:1.58.1-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 steps: - checkout - run: @@ -546,7 +546,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.54.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.58.1-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -565,7 +565,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.54.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.58.1-{{ checksum "Cargo.lock" }} # This runs one time on the top level to ensure all contracts compile properly into wasm. # We don't run the wasm build per contract build, and then reuse a lot of the same dependencies, so this speeds up CI time @@ -573,7 +573,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 steps: - checkout: path: ~/project @@ -582,7 +582,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -602,7 +602,7 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: | @@ -614,7 +614,7 @@ jobs: package_multi_test: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/multi-test steps: - checkout: @@ -624,7 +624,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-multi-test:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-multi-test:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -638,11 +638,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-multi-test:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-multi-test:1.58.1-{{ checksum "~/project/Cargo.lock" }} package_storage_plus: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project/packages/storage-plus steps: - checkout: @@ -652,7 +652,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-storage-plus:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-storage-plus:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target (no iterator) command: cargo build --locked --no-default-features @@ -669,11 +669,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-storage-plus:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-storage-plus:1.58.1-{{ checksum "~/project/Cargo.lock" }} benchmarking: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 environment: RUST_BACKTRACE: 1 steps: @@ -684,7 +684,7 @@ jobs: command: rustc --version && cargo --version - restore_cache: keys: - - cargocache-v2-benchmarking-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-benchmarking-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - run: name: Run storage-plus benchmarks working_directory: ~/project/packages/storage-plus @@ -693,7 +693,7 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-benchmarking-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-benchmarking-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} # This job roughly follows the instructions from https://circleci.com/blog/publishing-to-github-releases-via-circleci/ build_and_upload_contracts: @@ -743,7 +743,7 @@ jobs: build_and_upload_schemas: docker: - - image: rust:1.54.0 + - image: rust:1.58.1 working_directory: ~/project steps: - checkout: