diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 4486e2d46..73cc8e30c 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -11,7 +11,7 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, ThresholdResponse, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterListResponse, VoterResponse, }; -use cw_storage_plus::{Bound, OwnedBound}; +use cw_storage_plus::Bound; use crate::error::ContractError; use crate::msg::{HandleMsg, InitMsg, QueryMsg}; @@ -332,9 +332,9 @@ fn list_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = OwnedBound::exclusive_int(start_after); + let start = start_after.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range(&deps.storage, start.bound(), Bound::None, Order::Ascending) + .range(&deps.storage, start, None, Order::Ascending) .take(limit) .map(|p| map_proposal(&env.block, p)) .collect(); @@ -349,9 +349,9 @@ fn reverse_proposals( limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let end = OwnedBound::exclusive_int(start_before); + let end = start_before.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range(&deps.storage, Bound::None, end.bound(), Order::Descending) + .range(&deps.storage, None, end, Order::Descending) .take(limit) .map(|p| map_proposal(&env.block, p)) .collect(); @@ -394,12 +394,12 @@ fn list_votes( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let canon = maybe_canonical(deps.api, start_after)?; - let start = OwnedBound::exclusive(canon); + let start = canon.map(Bound::exclusive); let api = &deps.api; let votes: StdResult> = BALLOTS .prefix(proposal_id.into()) - .range(&deps.storage, start.bound(), Bound::None, Order::Ascending) + .range(&deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (key, ballot) = item?; @@ -435,11 +435,11 @@ fn list_voters( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let canon = maybe_canonical(deps.api, start_after)?; - let start = OwnedBound::exclusive(canon); + let start = canon.map(Bound::exclusive); let api = &deps.api; let voters: StdResult> = VOTERS - .range(&deps.storage, start.bound(), Bound::None, Order::Ascending) + .range(&deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (key, weight) = item?; diff --git a/packages/storage-plus/src/indexes.rs b/packages/storage-plus/src/indexes.rs index d896a94d6..c06e04f17 100644 --- a/packages/storage-plus/src/indexes.rs +++ b/packages/storage-plus/src/indexes.rs @@ -9,7 +9,7 @@ use cosmwasm_std::{Binary, Order, StdError, StdResult, Storage, KV}; use crate::map::Map; use crate::prefix::range_with_prefix; -use crate::{Bound, Endian}; +use crate::Endian; /// MARKER is stored in the multi-index as value, but we only look at the key (which is pk) const MARKER: u32 = 1; @@ -86,8 +86,8 @@ where { pub fn pks<'c>(&self, store: &'c S, idx: &[u8]) -> Box> + 'c> { let prefix = self.idx_map.prefix(idx); - let mapped = range_with_prefix(store, &prefix, Bound::None, Bound::None, Order::Ascending) - .map(|(k, _)| k); + let mapped = + range_with_prefix(store, &prefix, None, None, Order::Ascending).map(|(k, _)| k); Box::new(mapped) } diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 3a1ed18ae..d8bd42744 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -19,4 +19,4 @@ pub use keys::{PkOwned, Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key}; pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] -pub use prefix::{Bound, OwnedBound, Prefix}; +pub use prefix::{Bound, Prefix}; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 09a3e0305..dbe37f0a3 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -88,8 +88,8 @@ where pub fn range<'c, S: Storage>( &self, store: &'c S, - min: Bound<'_>, - max: Bound<'_>, + min: Option, + max: Option, order: cosmwasm_std::Order, ) -> Box>> + 'c> where @@ -200,9 +200,7 @@ mod test { PEOPLE.save(&mut store, b"jim", &data2).unwrap(); // let's try to iterate! - let all: StdResult> = PEOPLE - .range(&store, Bound::None, Bound::None, Order::Ascending) - .collect(); + let all: StdResult> = PEOPLE.range(&store, None, None, Order::Ascending).collect(); let all = all.unwrap(); assert_eq!(2, all.len()); assert_eq!( @@ -230,7 +228,7 @@ mod test { // let's try to iterate! let all: StdResult> = ALLOWANCE .prefix(b"owner") - .range(&store, Bound::None, Bound::None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -384,9 +382,7 @@ mod test { PEOPLE.save(&mut store, b"jim", &data2)?; // iterate over them all - let all: StdResult> = PEOPLE - .range(&store, Bound::None, Bound::None, Order::Ascending) - .collect(); + let all: StdResult> = PEOPLE.range(&store, None, None, Order::Ascending).collect(); assert_eq!( all?, vec![(b"jim".to_vec(), data2), (b"john".to_vec(), data.clone())] @@ -396,8 +392,8 @@ mod test { let all: StdResult> = PEOPLE .range( &store, - Bound::Exclusive(b"jim"), - Bound::None, + Some(Bound::Exclusive(b"jim".to_vec())), + None, Order::Ascending, ) .collect(); @@ -411,7 +407,7 @@ mod test { // get all under one key let all: StdResult> = ALLOWANCE .prefix(b"owner") - .range(&store, Bound::None, Bound::None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); assert_eq!( all?, @@ -423,8 +419,8 @@ mod test { .prefix(b"owner") .range( &store, - Bound::Exclusive(b"spender1"), - Bound::Inclusive(b"spender2"), + Some(Bound::Exclusive(b"spender1".to_vec())), + Some(Bound::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 d5433add5..65d55d896 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -14,11 +14,32 @@ use crate::Endian; /// 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 -#[derive(Copy, Clone, Debug)] -pub enum Bound<'a> { - Inclusive(&'a [u8]), - Exclusive(&'a [u8]), - None, +#[derive(Clone, Debug)] +pub enum Bound { + Inclusive(Vec), + Exclusive(Vec), +} + +impl Bound { + /// Turns optional binary, like Option into an inclusive bound + pub fn inclusive>>(limit: T) -> Self { + Bound::Inclusive(limit.into()) + } + + /// Turns optional binary, like Option into an exclusive bound + pub fn exclusive>>(limit: T) -> Self { + Bound::Exclusive(limit.into()) + } + + /// Turns an int, like Option into an inclusive bound + pub fn inclusive_int(limit: T) -> Self { + Bound::Inclusive(limit.to_be_bytes().into()) + } + + /// Turns an int, like Option into an exclusive bound + pub fn exclusive_int(limit: T) -> Self { + Bound::Exclusive(limit.to_be_bytes().into()) + } } #[derive(Debug, Clone)] @@ -59,8 +80,8 @@ where pub fn range<'a, S: Storage>( &self, store: &'a S, - min: Bound<'_>, - max: Bound<'_>, + min: Option, + max: Option, order: Order, ) -> Box>> + 'a> where @@ -72,68 +93,15 @@ where } } -/// OwnedBound is like bound, but owns the data (as a Vec) inside. -/// It is much easier to use if you dynamically construct the content, and can be passed into range as well. -/// We provide lots of helpers to create these bounds from other data-types -#[derive(Clone, Debug)] -pub enum OwnedBound { - Inclusive(Vec), - Exclusive(Vec), - None, -} - -impl OwnedBound { - /// Returns a bound that borrows the owned data, to pass into range() - pub fn bound(&self) -> Bound<'_> { - match self { - OwnedBound::Inclusive(limit) => Bound::Inclusive(&limit), - OwnedBound::Exclusive(limit) => Bound::Exclusive(&limit), - OwnedBound::None => Bound::None, - } - } - - /// Turns optional binary, like Option into an inclusive bound - pub fn inclusive>>(maybe: Option) -> Self { - match maybe { - Some(bytes) => OwnedBound::Inclusive(bytes.into()), - None => OwnedBound::None, - } - } - - /// Turns optional binary, like Option into an exclusive bound - pub fn exclusive>>(maybe: Option) -> Self { - match maybe { - Some(bytes) => OwnedBound::Exclusive(bytes.into()), - None => OwnedBound::None, - } - } - - /// Turns an int, like Option into an inclusive bound - pub fn inclusive_int(limit: Option) -> Self { - match limit { - Some(t) => Self::Inclusive(t.to_be_bytes().into()), - None => OwnedBound::None, - } - } - - /// Turns an int, like Option into an exclusive bound - pub fn exclusive_int(limit: Option) -> Self { - match limit { - Some(t) => Self::Exclusive(t.to_be_bytes().into()), - None => OwnedBound::None, - } - } -} - pub(crate) fn range_with_prefix<'a, S: Storage>( storage: &'a S, namespace: &[u8], - start: Bound<'_>, - end: Bound<'_>, + start: Option, + end: Option, order: Order, ) -> Box + 'a> { - let start = calc_start_bound(namespace, start, order); - let end = calc_end_bound(namespace, end, order); + let start = calc_start_bound(namespace, start); + let end = calc_end_bound(namespace, end); // get iterator from storage let base_iterator = storage.range(Some(&start), Some(&end), order); @@ -144,23 +112,21 @@ pub(crate) fn range_with_prefix<'a, S: Storage>( Box::new(mapped) } -// TODO: does order matter here? -fn calc_start_bound(namespace: &[u8], bound: Bound<'_>, _order: Order) -> Vec { +fn calc_start_bound(namespace: &[u8], bound: Option) -> Vec { match bound { - Bound::None => namespace.to_vec(), + None => namespace.to_vec(), // this is the natural limits of the underlying Storage - Bound::Inclusive(limit) => concat(namespace, limit), - Bound::Exclusive(limit) => concat(namespace, &one_byte_higher(limit)), + Some(Bound::Inclusive(limit)) => concat(namespace, &limit), + Some(Bound::Exclusive(limit)) => concat(namespace, &one_byte_higher(&limit)), } } -// TODO: does order matter here? -fn calc_end_bound(namespace: &[u8], bound: Bound<'_>, _order: Order) -> Vec { +fn calc_end_bound(namespace: &[u8], bound: Option) -> Vec { match bound { - Bound::None => namespace_upper_bound(namespace), + None => namespace_upper_bound(namespace), // this is the natural limits of the underlying Storage - Bound::Exclusive(limit) => concat(namespace, limit), - Bound::Inclusive(limit) => concat(namespace, &one_byte_higher(limit)), + Some(Bound::Exclusive(limit)) => concat(namespace, &limit), + Some(Bound::Inclusive(limit)) => concat(namespace, &one_byte_higher(&limit)), } } @@ -217,12 +183,10 @@ mod test { let expected_reversed: Vec<(Vec, u64)> = expected.iter().rev().cloned().collect(); // let's do the basic sanity check - let res: StdResult> = prefix - .range(&store, Bound::None, Bound::None, Order::Ascending) - .collect(); + let res: StdResult> = prefix.range(&store, None, None, Order::Ascending).collect(); assert_eq!(&expected, &res.unwrap()); let res: StdResult> = prefix - .range(&store, Bound::None, Bound::None, Order::Descending) + .range(&store, None, None, Order::Descending) .collect(); assert_eq!(&expected_reversed, &res.unwrap()); @@ -230,8 +194,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Inclusive(b"ra"), - Bound::None, + Some(Bound::Inclusive(b"ra".to_vec())), + None, Order::Ascending, ) .collect(); @@ -240,8 +204,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Exclusive(b"ra"), - Bound::None, + Some(Bound::Exclusive(b"ra".to_vec())), + None, Order::Ascending, ) .collect(); @@ -250,8 +214,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Exclusive(b"r"), - Bound::None, + Some(Bound::Exclusive(b"r".to_vec())), + None, Order::Ascending, ) .collect(); @@ -261,8 +225,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::None, - Bound::Inclusive(b"ra"), + None, + Some(Bound::Inclusive(b"ra".to_vec())), Order::Descending, ) .collect(); @@ -271,8 +235,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::None, - Bound::Exclusive(b"ra"), + None, + Some(Bound::Exclusive(b"ra".to_vec())), Order::Descending, ) .collect(); @@ -281,8 +245,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::None, - Bound::Exclusive(b"rb"), + None, + Some(Bound::Exclusive(b"rb".to_vec())), Order::Descending, ) .collect(); @@ -292,8 +256,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Inclusive(b"ra"), - Bound::Exclusive(b"zi"), + Some(Bound::Inclusive(b"ra".to_vec())), + Some(Bound::Exclusive(b"zi".to_vec())), Order::Ascending, ) .collect(); @@ -302,8 +266,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Inclusive(b"ra"), - Bound::Exclusive(b"zi"), + Some(Bound::Inclusive(b"ra".to_vec())), + Some(Bound::Exclusive(b"zi".to_vec())), Order::Descending, ) .collect(); @@ -312,8 +276,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Inclusive(b"ra"), - Bound::Inclusive(b"zi"), + Some(Bound::Inclusive(b"ra".to_vec())), + Some(Bound::Inclusive(b"zi".to_vec())), Order::Descending, ) .collect(); @@ -322,8 +286,8 @@ mod test { let res: StdResult> = prefix .range( &store, - Bound::Exclusive(b"ra"), - Bound::Exclusive(b"zi"), + Some(Bound::Exclusive(b"ra".to_vec())), + Some(Bound::Exclusive(b"zi".to_vec())), Order::Ascending, ) .collect();